View Controller Containment는 iOS 5에서 어떻게 작동합니까?


108

WWDC 2011 세션 (102), 애플은 유사한 사용자 지정보기 컨트롤러 컨테이너를 만들 수있는 기능이다보기 컨트롤러 봉쇄, 소개 UITabBarController, UINavigationController등을.

나는 예제를 여러 번 보았다. 이 패턴과 관련된 수많은 방법이 있지만 정확히 파악하기가 조금 어려웠습니다. 나는 여기에 내가 생각하는 일을 게시하고 커뮤니티가 내 의심을 확인하거나 반박 할 것인지를 볼 것입니다.

시나리오 1 : 부모 없음에서 새 부모 뷰 컨트롤러로 이동

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

처음 두 줄은 주어진 순서대로 나타나야합니까, 아니면 반대로 될 수 있습니까?

시나리오 2 : 상위 뷰 컨트롤러에서 상위 뷰 컨트롤러 없음으로 이동

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

전화도 필요합니까? [vc didMoveToParentViewController:nil] 합니까? 세션 (102)의 예는 이 작업을 수행하지 않은 이 시나리오에서,하지만 난 그가 누락되었거나 여부를 알 수 없습니다.

시나리오 3 : 상위 뷰 컨트롤러에서 다른 컨트롤러로 이동

이는 각 상위 뷰 컨트롤러의 논리가 캡슐화되기 때문에 다음과 같은 방식으로 발생할 수 있습니다.

// In the old parent
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

// In the new parent
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];

질문

내 주요 질문은 이것이다 : 이것이 일반적으로 뷰 컨트롤러 포함이 어떻게 작동해야 하는가? 위에 주어진 메커니즘이 정확합니까?

전화 willMoveToParentViewController하기 전에 전화 해야하나요addChildViewController 해야합니까? 이것은 나에게는 논리적 인 순서처럼 보이지만 반드시 필요합니까?

통화 didMoveToParentViewController:nil후 전화를 removeFromParentViewController해야합니까?

답변:


72

UIViewController문서는 때와하지 않을 때 호출에 꽤 명확하다 willMove/ didMove방법. 아웃 확인 "컨테이너 뷰 컨트롤러 구현" 문서를.

문서에서는을 재정의 addChildViewController하지 않으면 willMoveToParentViewController:메서드 를 호출 할 필요 가 없다고 말합니다 . 그러나 didMoveToParentViewController:전환이 완료된 후 메서드 를 호출해야합니다 . "마찬가지로, willMoveToParentViewController:메소드를 호출하기 전에 메소드를 호출하는 것은 컨테이너 뷰 컨트롤러의 책임입니다 removeFromParentViewController. removeFromParentViewController메소드는didMoveToParentViewController: 메서드는 자식 뷰 컨트롤러 ."

또한 여기에서 작업 한 예제 와 여기 에 샘플 코드가 있습니다 .

행운을 빕니다


17
그래서, 볼 addChildViewController과 균형을 이루어야 didMoveToParentViewControllerwillMoveToParentViewController함께 균형을 이루어야한다 removeFromParentViewController. 이것이 바로 제가 찾던 것입니다. 문서에서 어떻게 놓쳤는 지 잘 모르겠습니다.
Gregory Higley 2011

왜 안돼? 왜 willMoveToParentViewController를 호출 할 필요가 없지만 didMoveToParentViewController를 호출해야합니까?
user4951

그것이 문서가 말하는 것이기 때문입니다. 애플은 분명히 우리가 알 필요가 없다고 느낍니다.

7
그 이유는 애니메이션 때문입니다. 자신 만의 탐색 컨트롤러를 만들고 있다고 가정 해 보겠습니다. 슬라이드 인 애니메이션 시작시 'willMove'를 호출하고 애니메이션이 끝날 때 'didMove'를 호출해야합니다. 이제 애니메이션 시작 부분에 'addChild'를 호출하면 자동으로 'willMove'가 호출됩니다. 그러나 애니메이션 (있는 경우)이 언제 끝나는 지 알 수 없으므로 애니메이션이 끝날 때 (또는 애니메이션이없는 즉시) 'didMove'를 수동으로 호출해야합니다.
크리스

2
그리고 '슬라이드 아웃'애니메이션의 경우 (예 : 자식이 제거되는 경우) 애니메이션 시작시 수동으로 'willMove'를 호출해야합니다. 그렇지 않으면 uikit이 자식 VC의 'viewWillDisappear'를 호출해야하는시기를 알 수 없기 때문입니다. 그리고 애니메이션이 끝날 때 removeFromParentViewController를 호출하면 자동으로 'didMove'를 호출 할 수 있습니다.
Chris

23

이 부분은 올바르지 않습니다.

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

문서에 따르면 :

사용자 지정 컨테이너가 addChildViewController : 메서드를 호출하면 추가하기 전에 자식으로 추가 할 뷰 컨트롤러의 willMoveToParentViewController : 메서드를 자동으로 호출합니다.

그래서 당신은 [vc willMoveToParentViewController:self]전화 가 필요하지 않습니다 . 전화를 걸면 자동으로 이루어집니다 [self addChildViewController:vc]. 다시 코드 샘플은 다음과 같습니다.

[self addChildViewController:vc];
// [vc willMoveToParentViewController:self] called automatically
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

뷰 컨트롤러를 제거하려면 :

removeFromParentViewController 메서드는 자식을 제거한 후 자식 뷰 컨트롤러의 didMoveToParentViewController : 메서드를 자동으로 호출합니다.

아마도이 호출은 [oldVC didMoveToParentViewController:nil].

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// [vc didMoveToParentViewController:nil] called automatically

그렇지 않으면 작동하는 것처럼 보이더라도 presentingViewController가 presentingViewController에 설정되지 않은 것 같습니다.
Adrian

문서는 didMoveToParentViewController " addChildViewController : method를 호출 한 직후 "를 호출한다고 말하지만 실제로 자식 하위 뷰를 추가하는시기를 지정하지 않습니다. 나는 모든 사람들이 이것을 잘못 알고 있는지 궁금합니다. 일부 Apple Docs에이를 확인할 수있는 예제가 있습니까?
Robert

참고 : 당신은 호출 할 필요가 willMoveToParentViewController이전에 addChildViewController이동하려는 항목이 재정의와 사용자 정의 클래스 인 경우 addChildViewController(재정의 (override)가 내부적으로 호출하지 않는 한)
bunkerdive
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.