나는 연결된 내 응용 프로그램에서 이상한 행동을 발견 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()
완벽하게 작동했습니다 (스토리 보드에서 제약 조건을 수정하려고했습니다).