在 prepareForSegue 上为 Popover Segue 传递数据:iOS 5 中的奇怪行为
Posted
技术标签:
【中文标题】在 prepareForSegue 上为 Popover Segue 传递数据:iOS 5 中的奇怪行为【英文标题】:Passing data on prepareForSegue for a Popover Segue: strange behavior in iOS 5 【发布时间】:2013-02-25 08:14:53 【问题描述】:我注意到在 ios 5 中向弹出框传递数据时出现了一些奇怪的行为。在调用 prepareForSegue
之前调用了弹出框 viewDidLoad
方法:
在 Storyboard 中,segue 将 FirstViewController
的按钮连接到 PopoverViewController
,该按钮嵌入在导航控制器中。
为了测试,记录了两种方法:
/* FirstViewController.m */
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([segue.identifier isEqualToString:@"showPopover"])
NSLog(@"FirstViewController: prepareForSegue");
UINavigationController *navigationController = segue.destinationViewController;
PopoverViewController *popoverVC = (PopoverViewController *)navigationController.topViewController;
popoverVC.myProperty = @"Data to be passed";
在另一个 ViewController 中:
/* PopoverViewController.m */
- (void)viewDidLoad
[super viewDidLoad];
NSLog(@"PopoverViewController: viewDidLoad");
在 iOS 6 下,行为符合预期:
2013-02-25 09:03:53.747 FirstViewController: prepareForSegue
2013-02-25 09:03:53.751 PopoverViewController: viewDidLoad
在iOS 5 下PopoverViewController
的viewDidLoad
在prepareForSegue
之前被调用:
2013-02-25 09:05:28.723 PopoverViewController: viewDidLoad
2013-02-25 09:05:28.726 FirstViewController: prepareForSegue
这很奇怪,很难将数据传递给可在viewDidLoad
中使用的弹出框。有什么解决办法吗?
【问题讨论】:
解决方案是:你必须设置一个属性,然后才能在 viewDidLoad 中使用它。 【参考方案1】:我现在使用viewWillAppear:
方法而不是viewDidLoad
解决了这个问题。我认为无论如何这是配置视图的更好方法(因为视图可能已经加载并且应该在每次出现时配置视图)。
viewWillAppear:
方法在 iOS 5 和 iOS 6 中的 prepareForSegue
之后加载。
但是,对于那些需要viewDidLoad
的人来说,tkanzakic 建议的解决方案是当时可行的解决方案。
【讨论】:
仅供参考:viewWillAppear 可能会被多次调用。一个示例是当模型 VC 出现在 VC 上方并被关闭时。【参考方案2】:为您的属性创建一个自定义设置器并从那里执行您需要的操作,我习惯这样做:
- (void)setCity:(GLQCity *)city
if (_city != city)
_city = city;
[self configureView];
- (void)configureView
if (self.city)
...
- (void)viewDidLoad
[super viewDidLoad];
...
[self configureView];
【讨论】:
【参考方案3】:我对 iOS 5 和 6 之间的区别一无所知,但过去我也遇到过类似的困惑。如果您遵循一般经验法则:
-
prepareForSegue 在目标 VC 的 viewDidLoad 之前调用
viewDidLoad 仅在所有出口都加载后调用
因此,不要尝试在源 VC 的 prepareForSegue 中引用任何目标 VC 的出口。
然后,您自然会找到任一解决方案 - 实施 viewDidAppear 与 viewDidLoad,或仅设置目标 VC 的属性与触摸其任何出口。
关于 prepareForSegue 的另一个教训是避免冗余处理。例如,如果您已经通过情节提要将 tableView 单元格连接到 VC,如果您尝试同时处理 tableView:didSelectRowAtIndexPath 和 prepareForSegue,您可能会遇到类似的竞争条件。可以通过使用手动 segue 或放弃在 didSelectRowAtIndexPath 处的任何处理来避免这种情况。
【讨论】:
Re: tableView:didselectRow 我之前遇到过这个问题。好提示!以上是关于在 prepareForSegue 上为 Popover Segue 传递数据:iOS 5 中的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章
在 prepareForSegue 完成之前调用 viewDidLoad
在 didSelectRowAtIndexPath 之后 prepareForSegue?