web-dev-qa-db-de.com

Fügen Sie dem UINavigationController einen untergeordneten Ansichtscontroller hinzu

Ich versuche, eine untergeordnete Ansichtskontrolle einer UIViewController hinzuzufügen, die in einer UINavigationController enthalten ist, mit folgendem Code:

- (void)buttonTapped:(id)sender
{
    MyChildController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"MyChild"];
    [self addChildViewController:viewController];
    [self.view addSubview:viewController.view];
    [viewController didMoveToParentViewController:self];


    viewController.view.alpha = 0.0f;
    [UIView animateWithDuration:0.4 animations:^{
        viewController.view.alpha = 1.0f;
    }];
}

Aber das ist das Ergebnis:

Image Result

Wie Sie sehen, befinden sich UINavigatioBar und UIToolbar weiterhin auf dem untergeordneten Ansichtscontroller. Wie kann ich den Child-View-Controller auf alles setzen? Ich habe bereits versucht, den Code zu ersetzen durch:

[self.navigationController addChildViewController:viewController];
    [self.navigationController.view addSubview:viewController.view];
    [viewController didMoveToParentViewController:self.navigationController];

Aber auf diese Weise wird der viewDidAppear:animated der viewController nicht aufgerufen, weiß nicht warum.

12
Fred Collins

Führen Sie in Ihrem ersten View-Controller Folgendes aus:

- (IBAction)buttonClick:(id)sender
{
    SecondViewController *secondView = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    UIImage *blurryImage = [UIImage imageNamed:@"foo.jpeg"];
    secondView.imageView.image = blurryImage;
    [self.navigationController addChildViewController:secondView];
    secondView.view.frame = self.navigationController.view.frame;
    [self.navigationController.view addSubview:secondView.view];
}

Fügen Sie dann in Ihrem zweiten View-Controller den Getter für Ihre Bildansicht hinzu:

-(UIImageView *)imageView
{
    if( _imageView == nil )
    {
        _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 548)];
        [self.view addSubview:_imageView];
    }
    return _imageView;
}
6
JonahGabriel

Der Kommentar von @Sam ist korrekt. Sie müssen beginApperanceTransition:animated: und endAppearanceTransition aufrufen, damit viewDidAppear ausgelöst wird. Der Grund, warum UINavigationController beim Hinzufügen eines untergeordneten Ansichtscontrollers nicht viewDidAppear aufruft, liegt darin, dass er die Methoden zum Erstellen von Containern überschrieben hat, um zu verhindern, dass der Programmierer an fremden Orten einen untergeordneten Viewcontroller hinzufügt. In Ihrem Fall soll Ihre untergeordnete Ansicht die Navigationsleiste nicht verdecken. Die korrekte Verwendung eines Navigationscontrollers besteht darin, dass unter der Navigationsleiste Kinder angezeigt werden. Trotzdem können Sie diese nicht standardmäßige Benutzeroberfläche trotzdem erzwingen, indem Sie dem untergeordneten Element manuell mitteilen, wann es erscheint und wann es fertig ist.

Fügen Sie UINavigationController ein untergeordnetes Element hinzu

MyChildViewController* child = [[MyChildViewController alloc] init];
[self.navigationController addChildViewController:child];
child.view.frame = self.navigationController.view.bounds;
[self.navigationController.view addSubview:child.view];
child.view.alpha = 0.0;
[child beginAppearanceTransition:YES animated:YES];
[UIView
    animateWithDuration:0.3
    delay:0.0
    options:UIViewAnimationOptionCurveEaseOut
    animations:^(void){
        child.view.alpha = 1.0;
    }
    completion:^(BOOL finished) {
        [child endAppearanceTransition];
        [child didMoveToParentViewController:self.navigationController];
    }
];

Entfernen Sie ein Kind aus UINavigationController

[child willMoveToParentViewController:nil];
[child beginAppearanceTransition:NO animated:YES];
[UIView
    animateWithDuration:0.3
    delay:0.0
     options:UIViewAnimationOptionCurveEaseOut
    animations:^(void){
        child.view.alpha = 0.0;
    }
    completion:^(BOOL finished) {
        [child endAppearanceTransition];
        [child.view removeFromSuperview];
        [child removeFromParentViewController];
    }
];
30
Pwner

@Pwner s Antwort Swift-Version:

Kind zu UINavigaitonController hinzufügen

let child = MyChildViewController()
self.navigationController?.addChildViewController(child)
guard let navigationController = navigationController else {
    return
}
child.view.frame = navigationController.view.bounds
child.beginAppearanceTransition(true, animated: true)
self.navigationController?.view.addSubview(child.view)
self.view.alpha = 0
UIView.animate(withDuration: 0.3, animations: {
    child.view.alpha = 1.0
}, completion: { _ in
    guard let navigationController = self.navigationController else {
        return
    }
    child.endAppearanceTransition()
    child.didMove(toParentViewController: navigationController)
})

Entfernen Sie ein Kind aus UINavigationController

child.willMove(toParentViewController: nil)
child.beginAppearanceTransition(false, animated: true)
UIView.animate(withDuration: 0.3, animations: {
    child.view.alpha = 0.0
}, completion: { _ in
    guard let navigationController = self.navigationController else {
        return
    }
    child.view.removeFromSuperview()
    child.endAppearanceTransition()
    child.removeFromParentViewController()
})
0
Ivan Smetanin