[iphone] viewWillAppear : 및 viewDidAppear 간의 뷰 프레임 변경 :

나는 연결된 내 응용 프로그램에서 이상한 행동을 발견 IBOutlet받는 내보기 컨트롤러의 호출 사이의 연결 뷰의 프레임이 viewWillAppear:viewDidAppear:. 내 UIViewController하위 클래스 의 관련 코드는 다음과 같습니다 .

-(void)viewWillAppear:(BOOL)animated {
    NSLog(@"%@", self.scrollView);
}

-(void)viewDidAppear:(BOOL)animated {
    NSLog(@"%@", self.scrollView);
}

결과 로그 출력 :

MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 44; 320 416); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>

두 호출간에 프레임이 변경되고 있음을 명확하게 보여줍니다. viewDidLoad방법 의 뷰로 설정하고 싶었지만 화면에 나타날 때까지 내용을 변경할 수 없다면 꽤 쓸모없는 것 같습니다. 무슨 일이 일어날까요?



답변

Autolayout뷰의 GUI를 디자인하고 개발하는 방법에 큰 변화를 가져 왔습니다. 주요 차이점 중 하나는 autolayout뷰 크기를 즉시 변경하지 않고 트리거 된 경우에만 특정 시간에 의미하지만 제약 조건을 즉시 다시 계산하거나 레이아웃을 “필요한”것으로 표시하도록 강제 할 수 있다는 것입니다. 처럼 작동합니다 -setNeedDisplay.
저에게 큰 도전은 우리가 더 이상 자동 크기 조정 마스크를 사용할 필요가 없다는 것을 이해하고 받아들이는 것이었고, 프레임은 뷰를 배치하는 데 쓸모없는 속성이되었습니다. 더 이상 뷰 포지션에 대해 생각할 필요는 없지만 서로 관련된 공간에서 어떻게보고 싶은지 생각해야합니다.
오래된 자동 크기 조정 마스크와 자동 레이아웃을 혼합하려면 문제가 발생합니다. 우리는 곧 자동 레이아웃 구현에 대해 생각하고 자동 레이아웃을 기반으로하는 뷰 계층 구조에서 이전 접근 방식을 혼합하지 않도록해야합니다.
뷰 컨트롤러의 메인 뷰와 같이 자동 크기 조정 마스크 만 사용하는 컨테이너 뷰를 사용하는 것이 좋지만 혼합하지 않는 것이 좋습니다.
저는 스토리 보드를 사용한 적이 없지만 아마도 정확할 것입니다. 자동 레이아웃을 사용하면 자동 레이아웃 엔진이 계산을 시작할 때 뷰 프레임이 설정됩니다. - (void)viewDidLayoutSubviews뷰 컨트롤러의 수퍼 메서드 직후에 동일한 것을 요청하십시오 .
이 메서드는 자동 레이아웃 엔진이 뷰의 프레임 계산을 마치면 호출됩니다.


답변

로부터 문서 :

viewWillAppear:

뷰 컨트롤러에 뷰가 뷰 계층 구조에 추가 될 예정임을 알립니다.

viewDidAppear:

뷰가 뷰 계층에 추가되었음을 뷰 컨트롤러에 알립니다.

결과적으로 하위 뷰의 프레임은 아직에서 설정되지 않았습니다 viewWillAppear.

보기가 화면에 표시되기 전에 UI수정 하는 적절한 방법 은 다음과 같습니다.

viewDidLayoutSubviews

뷰 컨트롤러에 뷰가 하위 뷰를 배치했음을 알립니다.


답변

요구

self.scrollView.layoutIfNeeded ()

당신의 viewWillAppear방법에. 나중에 프레임에 액세스 할 수 있으며 인쇄 한 것과 동일한 값을 갖게됩니다.viewDidAppear


답변

제 경우에는 모든 프레임 관련 메서드를

override func viewWillLayoutSubviews()

완벽하게 작동했습니다 (스토리 보드에서 제약 조건을 수정하려고했습니다).


답변