重用故事板segue中涉及的细节UIViewController

时间:2014-09-29 20:29:11

标签: ios iphone uiviewcontroller

我在iPad上运行了一个主/详细应用程序。在横向模式下,我可以并排查看两个视图。 右/明细视图控制器包含MKMapView

问题是,当在 left / master 视图控制器中选择不同的表格单元格并且基本上重新执行segue时,整个详细视图控制器将被重新实例化。

这意味着我使用的MKMapView失去了用户的位置,并且基本上从头开始,从乡村规模放大到街道规模。

在执行segue之前,有没有办法确定显示的详细视图是否已经是我想要的,只是提供新数据并告诉它刷新?

例如:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    segueParkName = parkNames[indexPath.row]
    self.performSegueWithIdentifier("showParkDetails", sender: self)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showParkDetails" {
        let controller = (segue.destinationViewController as UINavigationController).topViewController as ParkDetailsController
        NSLog("Controller: \(controller)") // Different instance every time!
        controller.parkName = segueParkName
    }
}

喜欢

  1. 告诉iOS,到达prepareForSegue时,我可以提供一个重用的视图控制器,特别是(!)如果它&#39 ; s已经显示。

  2. didSelectRowAtIndexPath方法中,执行自定义segue并自行推送。但我真的很喜欢使用内置系统segues的想法,所以我不必具体说明我推动的内容和位置。使用Show Detail (eg. Replace)而不是定义我自己的设备似乎与设备无关。

2 个答案:

答案 0 :(得分:1)

我认为,在你的第一个建议中,一旦你准备好塞尔维亚,如果不是不可能放弃塞古,那将是麻烦的。所以我会选择你的第二个选项。但是如果您想要的详细视图控件已经到位,则根本不需要触发segue。所以而不是

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
segueParkName = parkNames[indexPath.row]
self.performSegueWithIdentifier("showParkDetails", sender: self)
}

你可能会有类似......

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
segueParkName = parkNames[indexPath.row]
self.detailViewController.parkName = segueParkName
}

这假设您已经有一个属性detailViewController指向您的详细ViewController。它还假设detailViewController将始终是您需要的 - 如有必要,请检查detailViewController类以查看它是否是您想要的MKMapView。最后,如果设置parkName没有达到你需要的一切(例如动画更改),那么只需在你的MkMapView中实现一个新方法,并调用它来代替设置parkName。

编辑为了扩展,您可以使用:

if self.detailViewController.isKindOfClass(yourMKMapViewSubclass) {
   self.detailViewController.parkName = segueParkName
}

测试detailViewController是否确实是你的MkMapView。

答案 1 :(得分:0)

您可以通过实现shouldPerformSegue来取消序列,但这是针对公园名称由于某种原因而无效的情况,以防止显示无效公园的视图控制器。

在这种情况下,解决方案是使用内置主控/详细信息模板为您执行的对主控制器中详细控制器的引用。然后在prepareForSegue中,从旧的细节控制器中获取地图,并将其放在新的控制器上。

随着您的应用程序变得越来越复杂,它可能不再适合主用户维护对详细信息控制器的引用。例如,如果您制作一个根控制器来推送一个新的母版,则当应用程序像模板应用程序一样处于纵向时,母版将找不到详细信息。因此,在这种情况下,实现拆分控制器委托的类也可以维护主/细节的上下文(即initWithSplitViewController)。通过在此类的init中通过类别在splitViewController上设置owningContext参数自身,然后可以从需要的位置访问它。例如。从母版上设置mapView。并在详细信息的loadView中从中获取mapView。