a Custom Segue that Simulates a Push Segue turns VC into Zombie

后端 未结 3 2038
粉色の甜心
粉色の甜心 2021-02-10 19:17

[To Make things short and clear]

I\'ve written a custom segue.

-(void)perform {
UIView *preV = ((UIViewController *)self.sourceViewController).view;
UI         


        
3条回答
  •  北恋
    北恋 (楼主)
    2021-02-10 19:31

    in iOS, the relationship between a viewController and it's .view is special.

    all of those runtime calls (initWithCoder: , UIStoryboardSegue initWithIdentifier:source:destination: , et al) point to an attempt to access something to do with the viewController behind the scenes, and the one thing you've done is removed it's main .view from where it was expected in its superview.

    by performing a removeFromSuperview on the .view of the sourceViewController, you are inviting havoc.

    if you want a view that is not a push-segue, you can make the segue a Modal segue. this will keep you from having to mess with the navigation-bar, and yet can allow the CocoaTouch runtime to do the work of the segue (and the cleanup afterwards) for you.

    if you really want control to stay in the same viewController, then you could modify your code to perform [preV setHidden:YES] or a [preV setAlpha:0]. it will still be there so it doesn't turn into a zombie, and you can get back to it by reversing whichever of the above two actions you prefer.

    you might even just try removing (or commenting out the call) to [preV removeFromSuperview], and sliding it back in when you return from whatever you're doing in newV.

    Edit

    Another thing to consider is the use of the __block Storage Type on the variable preV, since you are declaring it locally, and since you are leaving scope and the original viewController may be causing it to go away. in the completion block, you could end up with a reference to a variable that's already had its ref-count dropped to 0 and removed by the time you get there. __block is meant to prevent this.

提交回复
热议问题