2015-01-22 5 views
1

스토리 보드에 4 개의 장면이 있습니다. 한 장면은 컨테이너보기를 통해 다른 모든 장면의 부모 역할을합니다. 모든과 같이 배치 : 당신은 곁눈질 경우 네는 동일한 뷰 컨트롤러에서 서브 클래스되는 것을 알 수 있습니다여러 컨테이너 장면에서 공통 뷰 컨트롤러를 사용할 수 있습니까?

enter image description here

. 나는 각 장면 요소를 하나의 공통 뷰 컨트롤러에 연결하고 UIViewController를 네 번 서브 클래 싱하지 않도록이 작업을 수행했습니다. ProductDetailViewController 구현은 다음과 같습니다

@implementation ProductDetailViewController { 
    // Scene 1 
    __weak IBOutlet UINavigationBar *_navigationBar; 

    // Scene 2 
    __weak IBOutlet UILabel *_productName; 

    // Scene 3 
    __weak IBOutlet UILabel *_typeNameLabel; 
    __weak IBOutlet UILabel *_categoryNameLabel; 
    __weak IBOutlet UIImageView *_richImage; 

    // Scene 4 
    __weak IBOutlet UIImageView *_productImageView; 
} 

문제는 viewDidLoad 화재 (명백하게) 네 번 물건이 빈 게재되어 있다는 점이다. 디버거를 단계별로 살펴보면 제품 객체는 3 사이클 동안 nil이고 4 번째 사이클에서 초기화됩니다. 어쩌면보기 컨트롤러가 순서대로로드되고 있습니까?

어쨌든이 설정을해도 괜찮습니까? 모든 스토리 보드 씬에 대해 서브 클래 싱 된 뷰 컨트롤러를 피하는 더 좋은 방법이 있어야한다고 생각합니다.

+2

이미지와 설명에서 왜 3 대의 뷰 컨트롤러를 원하는지, 하나의 컨트롤러의 모든 서브 뷰가 3 개의 뷰가 아닌 것이 분명합니다. 이 세 명의 자식 컨트롤러에서 무엇을하고 싶습니까? – rdelmar

답변

0

이 네 장면에서 하나의보기 컨트롤러 클래스를 공유 할 수는 있지만 해당보기 컨트롤러 클래스에는 네 가지가 있지만 하나는 아닌 네 개의 인스턴스가 있습니다.

  • 을 당신이 가지고있는 스토리 보드 레이아웃을 유지하지만, 그 자체로, 각 자식 장면을 각각 고유의 뷰 컨트롤러 클래스를 사용

    내가이 접근 방식에 대해 조언을 것이며, 나도 제안했다 가졌 고유 한 IBOutlet 참조.

    자식보기 컨트롤러에 입력 된 데이터에 부모보기 컨트롤러가 액세스하게하려면 자식보기 컨트롤러가 부모보기 컨트롤러를 업데이트하도록 할 수 있습니다 (예 : 대리인 프로토콜 패턴 사용). 하지만 개인적으로 부모 뷰 컨트롤러에 자식 UIKit 속성을 노출하지는 않습니다. 뷰 컨트롤러는 다른 컨트롤러보기의 UIKit 개체에 액세스하는 것이 아니라 모델 데이터를 다시 전달합니다.

  • 별도의 컨트롤러가 필요하지 않은 경우 이러한 하위 뷰를 별도의 장면에 두지 마십시오. 여러분의 예제는 View Controller 포함의 매우 매력적인 용도로 보이지 않습니다. 내 마음 속에서, 그 자식 장면은 별도의 장면을 사용하는 것을 정당화하기 위해 (그리고 별도의 뷰 컨트롤러를 정당화하기 위해) 약간의 합리적인 수준의 복잡성을 가져야합니다. 그것들이 복잡하지 않다면 부모 뷰 컨트롤러에 하위 뷰를 추가하는 것만으로 컨테이너 뷰와 뷰 컨트롤러 포함을 사용하는 것이 훨씬 쉽습니다.

0

복수의 .xibs를 같은 클래스로 설정하는 것이 일반적입니다. UIViewController를 네 번 하위 클래스로 만들고 싶지도 않습니다.

하나의 문제는 부모보기 컨테이너와 모든 동일한 View Controller 클래스에 포함 된 하위보기 컨트롤러를 사용하여이 모든 작업을 수행 할 때 클래스가 서로 다른 4 개의 인스턴스를 작성하고 작성하는 경우 아무 것도 가정 할 수 없다는 것입니다. 너는 어느 쪽인가. 제품 객체가 없어지는 것은 놀라운 일이 아닙니다.

이 구조체는 복구 할 수 있으며 많은 권장 사항이 있지만 약간의 조정이 필요합니다. 좋은 방법은 학부모 - 대리인이 모든 결정을 내리는 것입니다.

  1. 는 자신의 종류의 클래스에게 위임 속성을 부여 물론 약함 (약한 아이는 살아있는 부모를 유지할 수 없기 때문에). 처음부터 위임자가있는 경우에는 자식이므로 위임자가없는 경우 상위가되므로 위의 코드에서 nil인지 확인할 수 있습니다. 하지만 대개는 알 필요가 없습니다.

  2. Segue 식별자를 사용하십시오. IB에서, 각 embed segues에 식별자를 부여하십시오. 그런 다음 뷰 컨트롤러 클래스에서,

    if ([segue.identifier isEqualToString:@"ProductNameIdentiferInStoryboard"]) { 
        /*...*/ } 
    else if ([segue.identifier isEqualToString:@"typeBarIdentiferInStoryboard"]) { 
        /*...*/ } 
    else if ([segue.identifier isEqualToString:@"productImageIdentifierInStoryboard"]) { /*...*/ } 
    
  3. 2 단계에서 prepareForSegue에서 다시 각각 childViewController을 대표하는 같은 종류의,

    @property ProductDetailViewController *productNameViewController; 
    @property ProductDetailViewController *productTypeBarViewController; 
    @property ProductDetailViewController *productImageBarViewController;` 
    
  4. 을 세 가지 속성을 구현 몸과 prepareForSegue:sender:을 구현, 패턴으로 채우기 : prepareForSeque:sender: 화재 전에

    self.productNameViewController = segue.destinationViewController; 
    self.productNameViewController.delegate = self; 
    
  5. 주 모든 viewDidLoad, 그래서 당신은 참조가 : 부모의 관점에서 여기에 모든 설정을 수행합니다. self.productNameViewController.titleLabel.text = @"Product Name"; nil에 메시지를 보내지 않아도 아무 것도하지 않아도 아이들이 먼저 불을 뿜으므로 상상의 아이들과 놀 수 있습니다. 그들은 정보를 보내거나 중요한 것을 물어볼 필요가있을 때 대의원이 있습니다.

이것은 성가신 것처럼 보일 수 있으며 식별자 항목은 분명히 있습니다. 그러나보기 컨트롤러를 처리하는 방법으로 IB에서 펼쳐지는 레이아웃으로 작업하면서 코드에서 중앙 집중식 제어를 유지하는 이점이 분명합니다.