UIModalTransitionStylePartialCurl with UITabBarController

后端 未结 2 1230
名媛妹妹
名媛妹妹 2020-12-01 19:47

This question has been asked a lot e.g. here but as far as I can see is yet to be answered in full.

I have a UITabBarController with a UINavigatio

2条回答
  •  北海茫月
    2020-12-01 20:31

    Tim Arnold's response worked great for me, thanks!

    One trap to watch out for: your modal page-curl transition will take over the whole screen if your content view controller is added as a child of the container view controller. You could just not add it as a child, but then none of the view lifecycle methods will get called on your content controller (e.g. viewDidLoad, viewWillAppear), which could be a problem.

    Fortunately, there is a way around this. In your container controller:

    • Add your content controller as a child in viewDidLoad
    • Remove it as a child in viewDidAppear
    • Re-add it as a child in viewWillDisappear.

    That way, your content controller gets its lifecycle methods called, while still being able to do a modal page-curl transition without taking up the whole screen.

    Here is the entire code of a bare-bones solution:

    @interface XXContainerController : UIViewController
    @property (strong, nonatomic) UIViewController *contentController;
    @property (nonatomic) BOOL curled;
    @end
    
    @implementation XXContainerController
    
    @synthesize contentController = _contentController;
    @synthesize curled = _curled;
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.contentController = [self.storyboard
            instantiateViewControllerWithIdentifier:@"SomeControllerInStoryboard"];
    
        // Add content controller as child view controller.
        // This way, it will receive all the view lifecycle events
        [self addChildViewController:self.contentController];
        self.contentController.view.frame = self.view.bounds;
        [self.view addSubview:self.contentController.view];
        [self.contentController didMoveToParentViewController:self];    
    }
    
    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    
        // Remove the content controller as child view controller.
        // This way, the modal page curl transition will
        // not take over the whole screen.
        // NOTE: need to wait until content controller has appeared
        // (which will happen later).
        // Achieve this by running the code at the end of the animation loop
        [UIView animateWithDuration:0 animations:nil completion:^(BOOL finished) {
            [self.contentController removeFromParentViewController];
        }];
    }
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
    
        // Add the content controller as child view controller again
        // so it receives the view lifecycle events
        [self addChildViewController:self.contentController];
    }
    
    - (void)setCurled:(BOOL)curled
    {
        if (curled == _curled) return;
    
        _curled = curled;
    
        // Curl up the content view and show underneath controller's view
        if (curled) {
            // Note you can specify any modal transition in storyboard
            // E.g. page curl, flip horizontal
            [self.contentController
                performSegueWithIdentifier:@"SomeModalSegueDefinedInStoryboard"
                sender:self];
    
        // Uncurl and show the content controller's view again
        } else {
            [self.contentController dismissModalViewControllerAnimated:YES];
    
            // Have to do this, otherwise the content controller's view
            // gets messed up for some reason 
            self.contentController.view.frame = self.view.bounds;
        }
    }
    
    @end
    

提交回复
热议问题