如何在主视图和详细视图之间分隔*没有*情节提要?
Posted
技术标签:
【中文标题】如何在主视图和详细视图之间分隔*没有*情节提要?【英文标题】:How to segue *without* storyboard between Master and Detail view? 【发布时间】:2015-06-23 15:21:31 【问题描述】:我已经完全以编程方式创建了一个主从项目,也就是说没有任何情节提要(我删除了文件)。
我不知道如何在主视图 (MV) 和详细视图 (DV) 之间进行切换
我试过了
self.showViewController(detailViewController, sender: self)
和
self.showDetailViewController(detailViewController, sender: self)
来自MV,但它并没有真正起作用。
我的 MV 的表格充满了单元格,当按下这些单元格时,应该会缩放到我 DV 中 mapView 上的注释。
由于某种原因,DV上的地图和MV中的表格在应用打开时第一次加载后没有刷新。
我正在使用自定义对象在视图之间传递数据
MV:
detailViewController.setRequired(self.customObject)
self.showDetailViewController(detailViewController, sender: self)
self.tableView.reloadData()
其中“setRequired”是将 DV 的类变量设置为来自 MV 的更新值的函数(至少这部分有效)
DV:
super.viewDidLoad()
mapView = MKMapView()
mapView.mapType = .Standard
mapView.frame = view.frame
mapView.delegate = self
view.addSubview(mapView)
self.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
self.navigationItem.leftItemsSupplementBackButton = true
populateMap(extractedObject)
其中“populateMap”是一个获取对象的函数(值是正确的,不用担心),旨在用新信息填充地图。
正如我所说,mapView 不会更新,表格也不会更新。
有什么想法吗?
(提醒一下,没有故事板文件,当然是故意的)
提前致谢!
乔纳
编辑
按照 vacawama 的回答:
是的,我的 masterViewController 嵌入在 UINavigationController 中。在MVC的viewDidLoad中我有
let controllers = self.splitViewController!.viewControllers
self.detailViewController = controllers[controllers.count-1].topViewController as DetailViewController,
但是当我尝试 self.navigationController.pushView... 建议时,我收到以下错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
上线let controllers = ...
编辑到编辑
即使解决了发现的 nil 问题,地图和表格似乎也没有上传。有什么想法吗?
【问题讨论】:
你之前没有提到SplitViewControllers。我给了你一个 iPhone 的答案。对于 SplitViewController,Master 和 Detail 同时在屏幕上,因此不需要加载新的 ViewController(这是 segue 所做的)。只需将您需要发送到 detailViewController 的数据写入一个或多个属性,然后调用一个方法让 detailViewController 刷新它的视图。您甚至可以在 detailVC 中的属性上使用didSet
自动执行此操作。
好的,谢谢。这可能很重要:我的 MVC 顶部有一个按钮,一旦按下它就会打开一个弹出视图。您在此弹出窗口中选择一些内容,然后按“更新” - 然后应该使用弹出窗口中的选定信息并相应地更新 MVC 和 DVC。有没有我应该从弹出窗口移回拆分视图的特定方式?现在我所做的只是在弹出框代码末尾的 self.dismissViewController(true, nil) 。再次感谢
我认为调用self.dismissViewController
来关闭弹出窗口很好。我假设在你这样做之前你将数据发送回调用者。
是的,我使用 let mcv = MasterViewController(),然后使用 mvc.function name(data)。 但是,地图和表格仍然没有改变。但是,如果我展示 ViewController(mvc),则会弹出正确更新的表格并覆盖屏幕。所以也许我需要类似的东西?再次感谢
【参考方案1】:
Segues 是一个故事板创作。如果你没有故事板,你就不能继续。如果您的 masterViewController
嵌入在 UINavigationController
中,则移动到 detailViewController
的编程方式是:
self.navigationController.pushViewController(detailViewController, animated: true)
如果您的 masterViewController
没有嵌入到 UINavigationController
中,那么您可以以模态方式呈现 detailViewController
:
self.presentViewController(detailViewController, animated: true, completion: nil)
更新:
在您更新的问题中,您提到了SplitViewController
。
我最初的回答给了你关于 iPhone 的信息。对于 SplitViewController,Master 和 Detail 同时在屏幕上,因此不需要加载新的 ViewController(这是 segue 所做的)。只需将您需要发送到detailViewController
的数据写入一个或多个属性,然后调用一个方法让detailViewController
刷新它的视图。您甚至可以在 detailViewController
中的属性上使用 didSet
自动执行此操作。
注意,当您更新 detailViewController
时,viewDidLoad
将不会运行。您需要提取更新 detailViewController
的 UI 的代码。称之为updateUI
。然后从viewDidLoad
和您的数据更新时调用updateUI
。我建议在您的 customData 属性上实现didSet
并从那里调用updateUI
。
【讨论】:
好的,非常感谢!我睡着了,所以延迟了以上是关于如何在主视图和详细视图之间分隔*没有*情节提要?的主要内容,如果未能解决你的问题,请参考以下文章
如何从情节提要中的 didSelectRowAtIndexPath 打开视图控制器?
如何在情节提要 Xcode 11 中的视图之间将边距设置为零