【问题标题】:Issue with custom segue's perform method after firing performSegueWithIdentifier触发 performSegueWithIdentifier 后自定义 segue 的 perform 方法出现问题
【发布时间】:2012-07-08 00:18:53
【问题描述】:

我有一个包含 2 个场景的故事板。每个场景都有一个 segue ctrl+从 ViewController 图标拖到另一个场景。从第一个视图到第二个视图的 Segue 具有标识符“left”,从第二个到第一个 -“right”,两个 Segue 都指向从 UIStoryboardSegue 继承的同一个自定义类。每个 ViewController 在 Attribute Inspector 中都有一个标题,并且还没有为它们分配任何自定义类。

在 AppDelegate 中,我为所有 4 个方向设置了 UISwipeGestureRecognizer,如果当前视图控制器具有标识符为“left”、“right”、“up”或“down”的 segue,它会触发 performSegueWithIdentifier:

- (void) handleSwipe:(UISwipeGestureRecognizer *) recognizer {
NSString *direction;
    switch ([recognizer direction]) {
        case UISwipeGestureRecognizerDirectionLeft:
            direction = @"left";
            break;
        case UISwipeGestureRecognizerDirectionUp:
            direction = @"up";
            break;
        case UISwipeGestureRecognizerDirectionDown:
            direction = @"down";
            break;
        default:
            direction = @"right";
            break;
    }
    @try {
        UIViewController *rootVC = self.window.rootViewController;
        [rootVC performSegueWithIdentifier:direction sender:rootVC];
    } @catch (NSException *e) {
        NSLog(@"Segue with identifier <%@> does not exist", direction);
    }
}

在我的自定义 Segue 类中,我按如下方式覆盖“执行”方法(没什么特别的,因为它会按原样中断,但我自然会覆盖它以便以后能够为 segues 自定义动画):

-(void) perform {
    UIViewController *src = (UIViewController *) self.sourceViewController;
    UIViewController *dst = (UIViewController *) self.destinationViewController;

    NSLog(@"source: %@, destination: %@", src.title, dst.title);

    [src presentModalViewController:dst animated:NO];
}

但是,它只在第一次向左滑动时有效,之后什么也没有发生。我可以通过“执行”方法中的 NSLog 看到 segue 的源视图控制器和目标视图控制器在第一次转换后由于某种原因没有改变,并且保持不变。看起来我错过了一些简单的东西,但我无法弄清楚。

别对我太苛刻 ;) ,我是 iOS 开发新手。

【问题讨论】:

    标签: iphone objective-c ios xcode ipad


    【解决方案1】:

    我认为这是因为您总是在 rootViewController 上执行 segue,而 segue 只是调用presentModalViewController。一个控制器一次只能有 1 个模态;如果你想继续呈现模态,你需要从堆栈顶部的视图控制器呈现它们。我不知道这是否是您的意思.. 除非您希望能够通过控制器堆栈向后弹出,否则继续显示模式实际上没有意义。

    如果您实际上不需要模态框,则可以将 segue 中的 rootViewController 替换为目的地:

    -(void) perform {
        UIViewController *dst = (UIViewController *) self.destinationViewController;
        // do some animation first
        [[[UIApplication sharedApplication] delegate].window.rootViewController = dst;
    }
    

    还应该注意的是,像您在问题中提到的那样,在应用程序委托上有一个手势识别器是非常奇怪的。实现您自己的 UIViewController 子类会更有意义,该子类执行滑动处理并在其自身上调用 performSegueWithIdentifier:

    【讨论】:

    • 非常感谢,它成功了!我同意应用程序委托中的手势识别器,但我不想在每个视图控制器上都有冗余代码,特别是如果我最终会有 20 个.在这种情况下你会推荐什么?
    • 您可以有一个基类,在viewDidAppear 或其他东西中添加手势识别器,然后让您的所有其他控制器从那里扩展。或者,如果继承对您的类来说过于严格,只需创建一个辅助方法;可能在 UIViewController 上有一个 Objective-c 类别。
    • 我确实想到了基类,但这是我能想到的唯一其他解决方案。想知道所有可能的情况。再次感谢 azethoth!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多