Josh Boothe
Josh Boothe

Reputation: 1423

How to retain a UIView controller (ARC)

These 4 files are relevant to this post:

The FirstViewController has a button (not on the nav bar, a separate button), when it is pressed, the page should curl up to present FilterViewController.

FirstViewController.h

- (IBAction)searchOptions:(id)sender;

FirstViewController.m:

- (IBAction)searchOptions:(id)sender {
    FilterViewController *ctrl = [[FilterViewController alloc] initWithNibName:@"FilterViewController" bundle:nil];
    [UIView transitionFromView:self.view toView:ctrl.view duration:1 options:UIViewAnimationOptionTransitionCurlUp completion:nil];

    [self.navigationController pushViewController:ctrl animated:NO];
}

On FilterViewController it has some UI stuff, you press a button, it saves the UI stuff and then the page curls back down to show the FirstViewController.

FilterViewController.h:

- (IBAction)backToMap:(id)sender;

FilterViewController.m:

- (IBAction)backToMap:(id)sender {
    FirstViewController *ctrl = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
        [UIView transitionFromView:self.view toView:ctrl.view duration:1 options:UIViewAnimationOptionTransitionCurlDown completion:nil];

        [self.navigationController popViewControllerAnimated:YES];
}

The issue here is with the retention of UIView. How can I retain the UIView?

When I click the button on FirstViewController the animation works and the page is presented. However on FilterViewController when I click the button it crashes to the debugger with the error:

EXC_BAD_ACCESS(code=2,address=0x8)

In the output console it says: (lldb)

After the page curl up I have a stepper, when I click the stepper I get the same error in the debugger.

UPDATE: I have tracked the memory location error: https://i.sstatic.net/Ye0Rm.png

Thanks.

Upvotes: 1

Views: 455

Answers (2)

Mikhail
Mikhail

Reputation: 4311

The issue here is that you try to make animation between view controllers with UIView's transition method.

According to documentation:

fromView
   The starting view for the transition. By default, this view is removed 
from its superview as part of the transition.
toView
   The ending view for the transition. By default, this view is added 
to the superview of fromView as part of the transition.

So, when you call this method, your ViewController's view replaced by another view with animation, and after on stack placed next ViewController without animation, so it's seems like all right (but your first controller's view already replaced).

But when you try to return some error behavior occurs - you replace view of controller, that will be removed.

So, i want to say, that i must be done more carefully, there several different approaches to make custom transition between viewControllers.

For example, you can watch next solution (it's similar to yours) - http://www.vigorouscoding.com/2011/05/custom-uiviewcontroller-transitions/

or

https://gist.github.com/jeksys/1507490

Upvotes: 0

isaac
isaac

Reputation: 4897

One thing I notice is that you're pushing a view controller, then pushing another view controller with the syntax "back". This may be the issue: A nav stack is a stack. If you start with view 0, push view 1, if you want to get back to view 0 you "pop" view 1 as opposed to pushing view 0 again.

So in:

- (IBAction)backToMap:(id)sender {
       FirstViewController *ctrl = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
        [UIView transitionFromView:self.view toView:ctrl.view duration:1 options:UIViewAnimationOptionTransitionCurlDown completion:nil];

        [self.navigationController popViewControllerAnimated:YES];
}

Upvotes: 3

Related Questions