Interface Builder IB - 导航控制器,跳过视图

Posted

技术标签:

【中文标题】Interface Builder IB - 导航控制器,跳过视图【英文标题】:Interface Builder IB - Navigation Controller, skipping a view 【发布时间】:2013-04-12 15:15:59 【问题描述】:

您好,我是 ios 新手,有一个关于浏览视图的问题。

我正在使用 IB 连接导航栏中的 PREVIOUS 和 NEXT 按钮来推动我的观点。这一切都很好。但是,我很难找出我需要做的确切位置或需要放置代码的位置,以便我可以跳过视图。为了简化我的情况...

-我有 1 个导航控制器和 4 个视图控制器,分别命名为 VC1、VC2、VC3、VC4。每个 VC 都有一个 .H/.M -从VC1开始,一个接一个。

假设我想跳过 VC3 并根据 VC2 中的设置直接跳转到 VC4。我将把代码放在哪里?我是否需要从 VC3 的 NAV 按钮中解开 IBAction 方法?

如果之前已经介绍过,我深表歉意。如果有一个 tut 或者如果你知道一个回答这个问题的帖子,请告诉我。我确实进行了搜索,但搜索返回的是通用帖子,可能是因为我使用了错误的术语。

提前致谢。

【问题讨论】:

您可以添加一些您编写的示例代码吗?你谈到了一些设置,所以设置意味着可能有一些变量。要跳过视图,您可以检查该变量并跳过 VC3 推入导航控制器。如果您分享您的代码,那么其他人将更容易回答您的问题。 感谢您抽出宝贵时间回复。对此,我真的非常感激。我不确定如何从情节提要中提取源代码,因为我只是 CTRL-从当前视图上的“下一步”按钮拖动到下一个场景的视图控制器。我应该更具体地了解变量,它实际上只是一个开/关开关,所以根据开关,我会去 VC3 或 VC4。再次感谢您的帮助。 我的建议是,虽然 ctrl 拖动以制作“下一个”segue 通常是最优雅的方法,但在执行需要编程控制的事情(例如,有选择地选择要转到哪个视图)时,那您将改为创建IBAction(在辅助编辑器中按住 ctrl 并拖动到 .h 文件并进行“操作”)。而且您绝对想使用 ctrl-drag 从“上一个”按钮到上一个场景。这是一场灾难。 Rob,为什么向后使用拖放方法会不好? [这不是我的视图的实现方式,我只是好奇。] 我认为导航控制器管理内存中的所有视图。想想看,我确实觉得处理“上一个”按钮与“下一个”按钮不同 @user2013871 我在你澄清你使用 unwind segues 返回之前写了这个,在这种情况下,你从控件拖动到出口出口,你会看到你的 unwind 出口,并且一切都是好的。但我在 S.O. 上见过很多人。谁,当第一次学习故事板时,使用 push segue 从 VC1 到 VC2,然后使用 push segue 从 VC2 回到 VC1,但实际上最终实例化了 VC1 的第二个副本,这就是问题所在。但是,如果您使用 unwind segue 到出口插座以从 VC2 回到 VC1,那么您就可以了。 【参考方案1】:

一些想法:

    如果您想从 VC2 推送到 VC3 或 VC4,而不是在特殊情况下让 VC3 立即推送到 VC4,我认为最好让 VC2 直接推送到适当的视图控制器。因此,您可能在 VC2 中有一个 IBAction 可以为您执行此操作:

    - (IBAction)pushToNext:(id)sender
    
        BOOL skipToVC4 = ... // put in whatever logic you'd use to bypass VC3 and go directly to VC4
        UIViewController *nextController;
    
        if (skipToVC4)
        
            nextController = [self.storyboard instantiateViewControllerWithIdentifier:@"VC4"];
    
            // obviously, if using NIBs, you'd do something like:
            // nextController = [[ViewController4 alloc] initWithNibName:@"VC4" bundle:nil];
        
        else
        
            nextController = [self.storyboard instantiateViewControllerWithIdentifier:@"VC3"];
        
    
        [self.navigationController pushViewController:nextController animated:YES];
    
    

    这样,当您从 VC4 弹回时,您将直接弹回适当的视图控制器(例如,如果您从 VC2 推送到 VC4,当您弹出时,您将自动弹回 VC2。

    而且,显然,如果您使用的是故事板,而不是手动调用 pushViewController,您可以从 VC2 获得两个 segue(一个到 VC3,一个到 VC4),给它们适当的标识符,然后调用 @987654324 @ 转到适当的视图控制器。但想法是一样的:您可以定义一个IBAction,根据您选择的任何逻辑执行适当的转场。

    您说您在导航栏中有“推送我的视图的上一个和下一个按钮”,我想知道您的“上一个”按钮。那是在做popViewControllerAnimated吗?通常,“NEXT”按钮将推送到新的视图控制器,但“PREVIOUS”按钮不应推送到前一个视图,而是弹回它。如果你不弹回来,你可能会得到你以前的一些视图控制器的多个实例。因此,“PREVIOUS”按钮应该链接到IBOutlet,它执行以下操作:

    - (IBAction)popToPrevious:(id)sender
    
        [self.navigationController popViewControllerAnimated:YES];
    
    

    当弹回时,您显然会弹回您从中推送的视图控制器。如果您想在返回 6.0 之前的 iOS 版本时跳过一些视图控制器,您可以使用popToViewControllerpopToRootViewControllerAnimated。例如,假设您从 VC1 推送到 VC2,再到 VC3,再到 VC4。如果你想从 VC4 一直跳回 VC1,你可以在 VC4 中连接和IBAction,比如:

    - (IBAction)popToRoot:(id)sender
    
        [self.navigationController popToRootViewControllerAnimated:YES];
    
    

    或者,如果你想从 VC4 跳回到 VC2,你会

    - (IBAction)popToVC2:(id)sender
    
        for (UIViewController *controller in self.navigationController.viewControllers)
        
            if ([controller isKindOfClass:[ViewController2 class]])
            
                [self.navigationController popToViewController:controller animated:YES];
                return;
            
        
    
    

    如果您将 VC2 的引用传递给 VC3,然后再传递给 VC4,则可以通过 navigationController.viewControllers 避免此迭代,但有时上述技术更容易。

    顺便说一句,如果您仅支持 iOS 6 及更高版本,并且正在使用情节提要,您还可以使用展开转场,这是一种更优雅的方式返回到特定的视图控制器。但尚不清楚(a)您是否使用故事板; (b) 你只支持 iOS 6 及更高版本,所以我将暂时避免讨论 unwind segues。

【讨论】:

非常感谢您的回复!这真的很有帮助,不仅回答了我的问题,而且您还提供了“以前”的思考点。 (续)...我正在使用 Interface Builder(故事板),我的目标是 ios6。我正在使用“unwindto ...”来处理我的“上一个”按钮操作。非常感谢您的详细回复。这真的很有帮助,并且可以更清楚地了解表单导航的工作原理。 @user2013871 - 啊,展开 segue 是完美的方式。我想我对你关于“推回”前一个控制器的评论读了太多。你正在放松,这是完美的! 不,是我。我还不熟悉术语。再次感谢!【参考方案2】:

首先:向我们展示一些代码,您将在其中推送新的视图控制器,也许是您的整个导航控制器代码

第二个(解决方案)

我假设:

您的上一个/下一个按钮链接到您的 navigationController 类 您有适当的方法 (prevPressed:/nextPressed:),当您单击其中一个按钮时会调用这些方法

我可以为您提供以下帮助:

您可以通过visibleViewController @property 知道当前哪个控制器可见 每次单击导航栏中的按钮时,您都可以询问visibleViewController 应该推送/弹出哪个下一个/上一个视图控制器

最好的解决方案是,如果您的所有控制器 VC1/2/3/4 都是 viewController 类的子类,它在其接口中定义了一个方法:

- (Class)nextViewControllerClass;
- (Class)previousViewControllerClass;

在实现中:

- (Class)nextViewControllerClass 
    return [VC4 class];


- (Class)previousViewControllerClass 
    return [VC1 class];

然后在您的 navigationController 代码中执行以下操作:

- (IBAction)next:(id)sender 
    UIViewController *nextViewController = [[[self.visibleViewController nextViewControllerClass] alloc] init];
    [self pushViewController:nextViewController animated:YES];

【讨论】:

感谢您抽出宝贵时间回复。这是很棒的东西。我确实在一本书中看到了这种方法来设置视图的外观和感觉。我怀疑在某个时候,我会这样做,但现在,我仍在努力弄清楚一切是如何运作的。再次感谢您花时间回复我的帖子。我真的很感激。

以上是关于Interface Builder IB - 导航控制器,跳过视图的主要内容,如果未能解决你的问题,请参考以下文章

Live Xcode 的 Interface Builder UIView 子类 (IB_DESIGNABLE) 没有 drawRect:

@IBDesignable 错误:IB Designables:无法更新自动布局状态:Interface Builder Cocoa Touch Tool 崩溃

如何使用 Interface Builder 中的自定义 UITableViewCell?

是否可以在 Interface Builder 中使用跟踪图像进行视图设计?

iOS:以编程方式更改从 Interface Builder 设置的约束

如何在 Interface Builder 中获取 iPhone,而不是 iPad 视图