programing tip

스토리 보드 내에서 자식보기 컨트롤러를 부모보기 컨트롤러에 연결

itbloger 2020. 12. 24. 23:24
반응형

스토리 보드 내에서 자식보기 컨트롤러를 부모보기 컨트롤러에 연결


Storyboard에서 자식보기 컨트롤러를 사용자 지정 컨테이너보기 컨트롤러에 연결할 수 있습니까?

자식보기 컨트롤러를 탭보기 컨트롤러에 연결할 수 있고 하나의보기 컨트롤러를 탐색 컨트롤러에 연결할 수 있습니다.

하위 VC를 수락하려면 컨테이너 VC에 어떻게해야합니까?


Caleb과 Matt의 답변을 조합하여 다음과 같이했습니다.

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"cpdc_check_embed"]) {
        self.checkVC = segue.destinationViewController;
    }
}

... checkVC컨테이너 컨트롤러의 속성은 다음과 같습니다.

@property (weak,nonatomic) PXPCheckViewController * checkVC;

embedsegue Storyboard ID를 원하는대로 설정하기 만하면됩니다 (이 경우 cpdc_check_embed).

Xcode에서 삽입 화면 확인

...에서 식별자를 확인합니다 -prepareForSegue:sender:.

여전히 콘센트는 아니지만 Matt (IMHO)보다 깨끗하고 Caleb보다 더 구체적이며 여전히 멋진 스토리 보드를 얻을 수 있습니다.

여기에 이미지 설명 입력


스토리 보드는 내장 된 컨테이너 뷰 컨트롤러를 매우 훌륭하게 다루며 하위 / 루트 뷰 컨트롤러에 대한 segue를 표시하여 관계가 명확하게 표시되도록합니다. 자식과 부모 뷰 컨트롤러가 다른 장면으로 분리되는 방법도 좋습니다.

자신의 프로젝트에서이 효과를 얻으려면 완벽하지는 않지만 매우 간단한 트릭이 있습니다. 내 예에서 'left'와 'right'라는 두 개의 탭만있는 탭 막대 컨트롤러처럼 작동하는 컨테이너 뷰 컨트롤러가 있다고 가정합니다. 한 장면이 부모 뷰 컨트롤러를 나타내고 두 개의 개별 장면이 '왼쪽'자식 뷰 컨트롤러와 '오른쪽'자식 뷰 컨트롤러를 모두 나타내도록하고 싶습니다.

불가능하지만 IBOutlet컨테이너 뷰 컨트롤러에서 다른 장면의 자식으로 s를 만든 다음 컨테이너 뷰 컨트롤러가 표시 될 때 UIViewController에 설명 된 규칙에 따라 부모 / 자식 관계를 설정할 수 있다면 좋을 것 입니다. 문서 . 'left'및 'right'자식 뷰 컨트롤러에 대한 참조가 있다면 문제없이 관계를 설정할 수 있습니다.

이 참조 문제에 대한 표준 솔루션은 Object아웃렛을 컨테이너 뷰 컨트롤러의 씬으로 드래그 한 다음 해당 클래스 유형을 자식 뷰 컨트롤러 클래스의 인스턴스로 지정 하여 자식 뷰 컨트롤러에 대한 참조를 만드는 것 입니다.

그러나 Apple의 내장 컨테이너와 같은 다른 장면에서 아이들을 분리시키기 위해 우리는 다른 트릭을 사용할 것입니다. 먼저 컨테이너 클래스에 다음과 같은 속성이 선언되어 있다고 가정합니다 ContainerViewController.

@property (nonatomic, strong, readwrite) UIViewController *leftViewController;
@property (nonatomic, strong, readwrite) UIViewController *rightViewController;

스토리 보드에서 '왼쪽'뷰 컨트롤러를 나타내는 장면을 선택합니다. 속성 검사기에서 뷰 컨트롤러의 identifier속성을 "cvc_leftViewController"( "cvc_"는를 참조 ContainerViewController하지만 실제로 식별자는 원하는 모든 것이 될 수 있음)로 설정합니다. 올바른 뷰 컨트롤러의 씬에 대해 동일하게 수행하여 식별자를 "cvc_rightViewController".

이제 다음 코드를 ContainerViewControllerviewDidLoad메소드에 삽입하십시오 .

if (self.storyboard) {
    _leftViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"cvc_leftViewController"];
    _rightViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"cvc_rightViewController"];
}

ContainerViewController스토리 보드에서가로드 되면 해당 장면에서 '왼쪽'및 '오른쪽'뷰 컨트롤러를 가져와 속성을 통해 참조를 설정합니다. 이제 자식 뷰 컨트롤러 인스턴스를 제어 할 수 있으므로 원하는대로 부모 / 자식 관계를 설정할 수 있습니다. 이를 올바르게 수행하는 방법을 배우려면 UIViewController 문서를 참조하십시오 .

이 트릭은 완벽하지 않고 많은주의 사항이 있지만주의하면 프로젝트에 잘 맞도록 만들 수 있습니다.

편집 : 이것은 완전히 불필요하고 아무 의미가 없지만, 정말로 당신이 정말로 당신의 컨테이너에서 당신의 자식 뷰 컨트롤러로의 스토리 보드 디스플레이 연결을 원한다면, 위의 방법을 사용하고 설정하십시오. 컨테이너 씬과 자식 씬 사이에서 직접 segues를 수행하고 단순히 이러한 segue를 수행하지 않습니다. 이제 모든 것이 올바르게 작동하고 예쁘게 보입니다.


Storyboard에서 자식보기 컨트롤러를 사용자 지정 컨테이너보기 컨트롤러에 연결할 수 있습니까?

여기서 물어 보는 것은 한 장면의 뷰 컨트롤러를 다른 장면의 뷰 컨트롤러의 콘센트에 연결하는 방법이라고 생각합니다. 스토리 보드 기계가 스토리 보드의 모든 장면을 동시에로드하지 못할 수도 있기 때문에 가능하다고 생각하지 않습니다.

한 장면에서 다음 장면으로 이동할 때 하나의 뷰 컨트롤러에서 다른 뷰 컨트롤러로 일부 정보를 전달하기를 원하기 때문에 이것을 묻는 것입니다. 스토리 보드로 작업 할 때이를 수행하는 방법 -prepareForSegue:sender:은 segue의 영향을받는 하나 또는 두 개의 뷰 컨트롤러에서 재정의 하는 것입니다. segue매개 변수에 제공된 UIStoryboardSegue 객체 에는 sourceViewControllerdestinationViewController속성 속성도 identifier있습니다. 이러한 속성을 사용하여 뷰 컨트롤러간에 데이터를 전송하려는 segue를 식별 할 수 있습니다.

Ray Wenderlich의 블로그에는 다음과 같이 도움이 될 수있는 스토리 보드 사용에 대한 멋진 두 부분의 자습서가 있습니다.

  • 1 부 에서는 스토리 보드 프로젝트 설정, 장면 추가 및 segue 만들기를 다룹니다.

  • Part 2 deals with using segues to transition between scenes, including the prepareForSeque method mentioned above.

iOS 5 allows multiple view controllers to be active in the same scene (although one should still be in charge), so a single scene in your storyboard might have several controllers. You can use outlets to connect these controllers to each other, and you can configure those connections the same way you did in IB: control-drag from one controller to another in the same scene. The usual outlet list will pop open to let you choose which outlet to connect.


The key to using multiple controllers in one scene (what I believe you are after here) is using the mysterious Object from the Objects list in IB to represent the other view controller and hooking up its outlets.

This answer How to create custom view controller container using storyboard in iOS 5 should help I hope. The answer also provides a working example app which is very helpful.


The problem with @Ben's (otherwise reasonable) answer is that it only works at one level of nesting. Beyond that, it would required that every subsequent VC is customized to save the nesting view controller in prepareForSegue.

To solve this, I spent too much time exploring an NSObject based index that that you could add to the Storyboard, bind to a scene, and which would then register it's parent VC in a global index, based on type and restorationId. That works / can work, but is too much effort in the end, and still requires the two step process of visually binding, and programmatically looking up.

For me, the simplest and most general solution is to lazily descend the view controller hierarchy

In my simple test project, I added the following lines to viewDidLoad:

    self.left.data = [
        "Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro.",
        "De carne lumbering animata corpora quaeritis." ]

where left is defined as:

lazy var left:CollectionViewController = { [unowned self] in
    return self.childViewControllerWithId("Left") as! CollectionViewController }()

and childViewControllerWithId is defined as:

extension UIViewController {
    func childViewControllerWithId(rid:String) -> UIViewController? {

        // check immediate child controllers
        for vc in self.childViewControllers as! [UIViewController] {
            if vc.restorationIdentifier == rid { return vc }
        }

        // check nested controllers
        for vc in self.childViewControllers as! [UIViewController] {
            if let vc = vc.childViewControllerWithId(rid) {
                return vc
            }
        }

        assert(false, "check your assumptions")
        return nil
    }
}

Note that you could do other find variants based on type, if need be. Also note that the above requires that you define the restoration id in the Storyboard file. If you did not have repeated instances of the same view controller, then using type would be easier.

And to state what is hopefully obvious, you don't need to implement prepareForSegue, nor do you have to use the lazy loading, you just have to call find(...).

참조 URL : https://stackoverflow.com/questions/8198698/linking-child-view-controllers-to-a-parent-view-controller-within-storyboard

반응형