使用故事板编程方式推送视图控制器的替代方法

57
我正在寻找在代码中以编程方式实例化的视图控制器的替代推送方法。 实际上,我已经找到了两种方法,我用这些方法去到下一个视图,也可以返回前一个视图:
  1. 使用pushViewController

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle: nil]; 
    LocationWebView *lvc = [storyboard instantiateViewControllerWithIdentifier:@"LocationWebView"];
    [self.navigationController pushViewController:lvc animated:YES];
    
  2. 以编程方式执行Segue

    [self performSegueWithIdentifier: @"SongSegue" sender: self];
    
    你有没有一些替代方案的提示以及这个操作应该如何执行的最佳方法?请注意,我不是指模态视图。

个人而言,如果您正在使用Storyboard和segues,那么#2是更好的方法。 - Mike K
如果您必须推送一个不能使用segue的视图控制器,例如从地图视图注释的披露按钮中推送视图控制器,那么#1可能会有用吗? - kappa
任何东西都可以有一个segue。但不是所有东西都可以在IB中完全自动地拥有segue(例如按钮和表格单元格)。但您仍然可以从视图控制器本身开始在IB中创建segue,并使用#2来执行它;这正是您为地图标注按钮所做的事情。 - rickster
如果您在故事板中表示目标视图控制器(基本上必须这样做才能使用segue),我建议使用#2。但是,如果您正在编程创建视图控制器(例如非常简单/单次使用的视图控制器),则使用#1(或者仅使用最后一行)。 - devios1
2个回答

36

苹果推荐使用 performSegueWithIdentifier:sender:someObject 来以编程方式执行转场。这样做至少有几个优点:

  • 少写代码 意味着你让框架做更多的工作。如果苹果在将来的 iOS 版本中推出了一些超级酷的新视觉效果用于 push 转场,或者改进了性能,或者修复了一些 bug,你的应用可以免费获得它们。而你编写的每一行代码来做框架可以为你完成的工作都增加了编写错误的机会。

  • 更多地使用 IB 可以意味着更容易进行更改。如果你决定要将所有的 push 转场更改为 modal 转场,或者某种自定义的转场类型(其中你可以实现自己的超级酷的视觉效果),你可以在 IB 中选择它们并通过单击来更改转场类型,而不是在代码中寻找。


此外,无论您使用哪种方法,在推送视图控制器以返回到前一个视图控制器时,其效果并不是用户期望的。当你推送一个 SongViewController 时,它会被添加到导航栈的末尾:

LocationViewController -> SongViewController

如果您再次按下 LocationViewController 来返回:

LocationViewController -> SongViewController -> LocationViewController

如果用户在导航栏中点击返回按钮,则会从位置视图返回到歌曲视图,然后再返回到位置视图。 (此外,如果您一直这样做,“返回”和“前进”每次都会增加一个不断增长的视图控制器链,可能会导致其他问题。)

相反,您应该让导航控制器处理返回。 它会在导航栏中放置一个按钮,用于此目的,应该可以处理大多数用例。 如果您需要自己创建返回控件,则无法在 iOS 5 中使用 IB 完成,但是您可以通过导航控制器的 popViewControllerAnimated: 方法以编程方式完成。


4

个人而言,在被UINavigationController管理的UIViewController中,我使用#2。如果没有UINavigationController,我认为它不起作用。

当我在使用一个被UITabBarController管理的视图时,我使用以下代码来切换到另一个选项卡:

NSUInteger tabIndex = 2; // Index of the tab I want to select
UIViewController * viewCtrl = [_tabController.viewControllers objectAtIndex:tabIndex];
_tabController.selectedViewController = viewCtrl;

2
objectAtIndex:0 应该改为 objectAtIndex:tabIndex 吗? - Kevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接