Pergunta

I've implemented a nice interface using storyboards, and I decided I wanted a fancier animation for presenting another view controller. This animation, to be consistent, requires both a segue, and an unwind segue. So I created my segue to support both:

@interface FKCircularSegue : UIStoryboardSegue

/// If it's an unwind segue
@property (nonatomic,assign) BOOL unwind;

@property (nonatomic,assign) CGRect frameCircle;

@end

It works great when doing the segue and unwinding. For unwinding I implemented the method:

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
{
    if ([identifier isEqualToString:@"camera.take.close"])
    {
        // Circular segue!
        FKCircularSegue *segue = [[FKCircularSegue alloc] initWithIdentifier:identifier source:fromViewController destination:toViewController];

        segue.frameCircle  = _frameCameraButtonTapped;
        segue.unwind        = YES;

        return segue;
    }

    return [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
}

BUT! I noticed that all other normal unwind segues, coming back from pushes and modals (this is sort of a central view controller) stopped working, so clearly, [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier] isn't doing it.

Weirdly enough, the debugger shows that it's actually returning an UIStoryboardSegue, but it doesn't do anything, tapping on a button that normally would "pop" you back to this view controller does nothing.

On the other hand, if I comment out the whole segueForUnwind... method, it goes back to normal, so the default implementation that UIViewController has is the right one.

In short, my problem is, how can I support one custom unwind segue, but then use the default ones for every other unwind segue?

Foi útil?

Solução

Well, I figured out the issue.

Ends up that the super method is alright, the problem lies on a UINavigationController subclass that I made that forwards the call to this view controller.

To fix it, I added a protocol that any view controller can implement, and basically asks if it wants to take care of the unwind segue, or it should be done automatically by the navigation controller.

It's very verbose, but I think it's better than the solution posted prior to the edit.

FKNavigationController.h

/**
 *  Implement this if you want custom unwind segues
 */
@protocol FKNavigationControllerSegueForwarding <NSObject>

- (BOOL)shouldPerformUnwindSegueFromNavigationControllerWithIdentifier:(NSString*)identifier fromViewController:(UIViewController*)viewController;

@end

/**
 *  Automatically forwards segue methods
 */
@interface FKNavigationController : UINavigationController

@end

FKNavigationController.m

@implementation FKNavigationController

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
{
    if ([toViewController respondsToSelector:@selector(shouldPerformUnwindSegueFromNavigationControllerWithIdentifier:fromViewController:)])
    {
        if ([(id<FKNavigationControllerSegueForwarding>)toViewController shouldPerformUnwindSegueFromNavigationControllerWithIdentifier:identifier fromViewController:fromViewController])
        {
            return [toViewController segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
        }
    }

    return [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
}

@end

Updated View Controller

#pragma mark - Segue forwarding

- (BOOL)shouldPerformUnwindSegueFromNavigationControllerWithIdentifier:(NSString *)identifier fromViewController:(UIViewController *)viewController
{
    if ([identifier isEqualToString:@"camera.take.close"])
    {
        return YES;
    }

    return NO;
}

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
{
    // Check the FKNavigationControllerSegueForwarding if you want to add more.
    if ([identifier isEqualToString:@"camera.take.close"])
    {
        // Circular segue!
        FKCircularSegue *segue = [[FKCircularSegue alloc] initWithIdentifier:identifier source:fromViewController destination:toViewController];

        segue.frameCircle  = _frameCameraButtonTapped;
        segue.unwind        = YES;

        return segue;
    }

    return [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top