[ios] layoutSubviews는 언제 호출됩니까?

layoutSubview애니메이션 중에 메시지 가 표시되지 않는 사용자 정의보기가 있습니다.

화면을 채우는 뷰가 있습니다. 탐색 표시 줄의 높이를 변경하면 인터페이스 빌더에서 올바르게 크기가 조정되는 화면 하단에 사용자 정의 하위보기가 있습니다. layoutSubviews뷰가 생성 될 때 호출되지만 다시는 호출되지 않습니다. 내 소견이 올바르게 배치되었습니다. 통화 중 상태 표시 줄을 끄면 layoutSubviews기본보기가 크기 조정에 애니메이션을 적용하더라도 하위보기 가 전혀 호출되지 않습니다.

어떤 상황에서 layoutSubviews실제로 불려지 는가?

나는 한 autoresizesSubviews설정 NO내 사용자 정의보기를. 그리고 Interface Builder에는 상단 및 하단 스트럿과 수직 화살표가 있습니다.


퍼즐의 또 다른 부분은 창을 열쇠로 만들어야한다는 것입니다.

[window makeKeyAndVisible];

그렇지 않으면 하위 뷰의 크기가 자동으로 조정되지 않습니다.



답변

비슷한 질문이 있었지만 대답 (또는 인터넷에서 찾을 수있는 것)에 만족하지 못했기 때문에 실제로 시도해 보았습니다.

  • initlayoutSubviews(duh)라고 부르지 않습니다
  • addSubview:원인
    layoutSubviews추가되는 뷰라고하는 뷰는 그것 (목표 뷰)을 첨가하고, 타겟의 모든 파단되는 것
  • 도면 setFrame
    지능적 호출 layoutSubviews프레임의 크기 파라미터가 다른 경우에만 해당 프레임 세트를 갖는보기
  • UIScrollView를 스크롤 layoutSubviews하면 scrollView 및 그 superview에서 호출됩니다.
  • 장치를 회전 layoutSubview하면 상위 뷰 에서만 호출
    (응답 viewControllers 기본 뷰)
  • 뷰 크기를 조정하면 layoutSubviews수퍼 뷰 가 호출 됩니다.

내 결과 -http : //blog.logichigh.com/2011/03/16/when-does-layoutsubviews-get-called/


답변

@BadPirate의 이전 답변을 바탕으로 조금 더 실험하고 설명 / 수정 사항을 제시했습니다. 다음 layoutSubviews:과 같은 경우에만 뷰에서 호출됩니다.

  • 자체 경계 (프레임 아님)가 변경되었습니다.
  • 직접 서브 뷰 중 하나의 경계가 변경되었습니다.
  • 서브 뷰가 뷰에 추가되거나 뷰에서 제거됩니다.

관련 정보 :

  • 범위는 다른 원점을 포함 하여 새 값이 다른 경우에만 변경된 것으로 간주됩니다 . 특히 layoutSubviews:경계의 원점을 변경하여 스크롤을 수행하므로 UIScrollView가 스크롤 될 때마다 호출됩니다.
  • 프레임을 변경하면 크기가 변경된 경우에만 경계가 변경됩니다. 이것이 경계 속성으로 전파되는 유일한 것입니다.
  • 뷰 계층 구조에 아직없는 뷰의 경계가 변경 layoutSubviews: 되면 뷰가 결국 뷰 계층 구조에 추가 될 때 호출됩니다 .
  • 그리고 완전성을 위해 :이 트리거는 layoutSubviews를 직접 호출 하지 않고 오히려 setNeedsLayout플래그를 설정 / 발생시키는 call을 호출 합니다. 실행 루프의 각 반복은 보기 계층의 모든보기 대해이 플래그가 검사됩니다. 플래그가 발견 된 각 뷰에 대해 layoutSubviews:호출되고 플래그가 재설정됩니다. 계층 구조보다 높은 뷰는 먼저 확인 / 호출됩니다.

답변

https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW1

보기에서 다음 이벤트가 발생할 때마다 레이아웃 변경이 발생할 수 있습니다.

ㅏ. 뷰의 경계 사각형 크기가 변경됩니다.
비. 일반적으로 루트 뷰의 경계 사각형에서 변경을 트리거하는 인터페이스 방향 변경이 발생합니다.
씨. 뷰의 레이어와 관련된 핵심 애니메이션 하위 레이어 세트가 변경되고 레이아웃이 필요합니다.
디. 응용 프로그램은  뷰 의 setNeedsLayout 또는  layoutIfNeeded메소드를 호출하여 레이아웃이 발생  하도록합니다.
이자형. 응용 프로그램은 setNeedsLayout 뷰의 기본 레이어 객체의 메서드를 호출하여 레이아웃을 강제  합니다.


답변

에있는 점의 일부 BadPirate의 대답은 부분적으로 만 해당 :

  1. 대한 addSubView포인트

    addSubview 추가중인보기, 추가중인보기 (대상보기) 및 대상의 모든 하위보기에서 layoutSubviews를 호출합니다.

    뷰의 (대상 뷰) 자동 크기 조정 마스크에 따라 다릅니다. 자동 크기 조정 마스크가 켜져 있으면 각에서 layoutSubview가 호출됩니다 addSubview. 자동 크기 조정 마스크가 없으면 view의 (대상보기) 프레임 크기가 변경 될 때만 layoutSubview가 호출됩니다.

    예 : 프로그래밍 방식으로 UIView를 만든 경우 (기본적으로 자동 크기 조정 마스크가 없음) LayoutSubview는 UIView 프레임이 모두 변경되지 않은 경우에만 호출됩니다 addSubview.

    이 기술을 통해 응용 프로그램의 성능도 향상됩니다.

  2. 장치 회전 지점

    장치를 회전하면 상위 뷰 (응답 viewController의 기본 뷰)에서 layoutSubview 만 호출합니다.

    이는 VC가 VC 계층 (root at window.rootViewController) 에있을 때만 해당 될 수 있습니다 . 가장 일반적인 경우입니다. iOS 5에서 VC를 만들지 만 다른 VC에 추가되지 않으면 장치가 회전 할 때이 VC가 통지를받지 않습니다. 따라서 layoutSubviews를 호출해도 해당 뷰가 표시되지 않습니다.


답변

시뮬레이션 된 화면 요소가 설정된 뷰 (상태 표시 줄 등)에서 스프링을 변경할 수 없다는 Interface Builder의 주장에 대한 솔루션을 추적했습니다. 스프링이 메인 뷰에서 꺼 졌기 때문에 뷰가 크기를 변경할 수 없으므로 호출 막대가 나타날 때 전체가 아래로 스크롤되었습니다.

시뮬레이션 된 기능을 끄고보기의 크기를 조정하고 스프링을 올바르게 설정하면 애니메이션이 발생하고 메서드가 호출되었습니다.

이를 디버깅 할 때의 또 다른 문제점은 메뉴를 통해 통화 중 상태가 전환 될 때 시뮬레이터가 앱을 종료한다는 것입니다. 앱 종료 = 디버거 없음


답변

호출
[self.view setNeedsLayout];
의 ViewController에서하는 전화 viewDidLayoutSubviews에 있습니다


답변

layoutIfNeeded를 보셨습니까?

설명서 스 니펫은 다음과 같습니다. 애니메이션 중에이 메서드를 명시 적으로 호출하면 애니메이션이 작동합니까?

layoutIfNeeded 필요한 경우 하위보기를 배치합니다.

- (void)layoutIfNeeded

토론이 방법을 사용하여 그리기 전에 하위 뷰의 레이아웃을 강제로 적용하십시오.

사용 가능 iPhone OS 2.0 이상에서 사용 가능합니다.