【问题标题】:Passing data on prepareForSegue for a Popover Segue: strange behavior in iOS 5在 prepareForSegue 上为 Popover Segue 传递数据: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 下PopoverViewControllerviewDidLoadprepareForSegue 之前被调用:

2013-02-25 09:05:28.723 PopoverViewController: viewDidLoad
2013-02-25 09:05:28.726 FirstViewController: prepareForSegue

这很奇怪,很难将数据传递给可在viewDidLoad 中使用的弹出框。有什么解决办法吗?

【问题讨论】:

  • 解决方案是:你必须设置一个属性,然后才能在 viewDidLoad 中使用它。

标签: ios ipad ios5 uipopovercontroller uistoryboardsegue


【解决方案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 之间的区别一无所知,但过去我也遇到过类似的困惑。如果您遵循一般经验法则:

    1. prepareForSegue 在目标 VC 的 viewDidLoad 之前调用
    2. viewDidLoad 仅在所有出口都加载后调用
    3. 因此,不要尝试在源 VC 的 prepareForSegue 中引用任何目标 VC 的出口。

    然后,您自然会找到任一解决方案 - 实施 viewDidAppear 与 viewDidLoad,或仅设置目标 VC 的属性与触摸其任何出口。

    关于 prepareForSegue 的另一个教训是避免冗余处理。例如,如果您已经通过情节提要将 tableView 单元格连接到 VC,如果您尝试同时处理 tableView:didSelectRowAtIndexPath 和 prepareForSegue,您可能会遇到类似的竞争条件。可以通过使用手动 segue 或放弃在 didSelectRowAtIndexPath 处的任何处理来避免这种情况。

    【讨论】:

    • Re: tableView:didselectRow 我之前遇到过这个问题。好提示!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    相关资源
    最近更新 更多