关闭模式视图但保留数据
Posted
技术标签:
【中文标题】关闭模式视图但保留数据【英文标题】:Dismissing a modal view but keeping the data 【发布时间】:2017-02-13 21:41:13 【问题描述】:我试图关闭模态视图并返回到“发送”自的视图控制器,同时保留在模态视图中输入的数据。如果我理解正确,我需要为此使用委托/协议,但我很难理解如何在这种情况下实际实现它。
基本上用户可以调用模态视图在文本字段中输入一些信息,当他们点击保存时,这个函数被调用:
func handleSave()
guard let newProductUrl = NSURL(string: urlTextField.text!) else
print("error getting text from product url field")
return
guard let newProductName = self.nameTextField.text else
print("error getting text from product name field")
return
guard let newProductImage = self.logoTextField.text else
print("error getting text from product logo field")
return
// Call save function in view controller to save new product to core data
self.productController?.save(name: newProductName, url: newProductUrl as URL, image: newProductImage)
// Present reloaded view controller with new product added
let cc = UINavigationController()
let pController = ProductController()
productController = pController
cc.viewControllers = [pController]
present(cc, animated: true, completion: nil)
它调用self.productController?.save
函数将新输入的值保存到核心数据中,并使用新产品重新加载productController
表视图。
但是我遇到的问题是 productController
表视图是根据其他一些因素动态设置的,所以我只想在用户输入数据后关闭模式视图,然后返回调用模态视图的页面。
编辑:尝试了解如何实现委托 -
ProductController 是用户访问模态视图的父类:
protocol ProductControllerDelegate: class
func getData(sender: ProductController)
class ProductController: UITableViewController, NSFetchedResultsControllerDelegate, WKNavigationDelegate
override func viewDidLoad()
super.viewDidLoad()
weak var delegate:ProductControllerDelegate?
func getData(sender: ProductController)
AddProductController 是模态呈现的控制器,用户在其中输入数据,然后调用 handleSave
,我想关闭并返回调用它的 ProductController 表视图:
class AddProductController: UIViewController, ProductControllerDelegate
override func viewDidDisappear(_ animated: Bool)
// error on this line
getData(sender: productController)
【问题讨论】:
【参考方案1】:如果您的协议的唯一目的是返回视图控制器的最终状态,则使用展开转场而不是协议通常更容易和更清晰。
步骤:
1) 在父 VC 中创建一个 @IBAction unwind(segue: UIStoryboardSegue) 方法
2) 在呈现的 ViewController 的情节提要中,您可以控制从要触发退出的控件或黄色视图控制器本身(如果在代码中执行 segue)拖动到橙色退出图标。
您的代码应如下所示:
@IBAction func unwind(segue: UIStoryboardSegue)
if let source = segue.source as? MyModalViewController
mydata = source.data
source.dismiss(animated: true, completion: nil)
see apple documentation
这里的编辑是在没有情节提要的情况下触发和放松代码的黑客方式;我不赞成这样做:
guard let navigationController = navigationController,
let presenter = navigationController.viewControllers[navigationController.viewControllers.count - 2] as? MyParentViewController else
return
presenter.unwind(UIStoryboardSegue(identifier: String(describing: self), source: self, destination: presenter))
【讨论】:
这是唯一的目的,所以我现在会尝试这种方式而不是委托,出于某种原因,我发现委托对于这样看似简单的任务真的很困惑..我是虽然不使用情节提要,但这都是程序化的。 您只能使用情节提要来做到这一点。否则你必须使用hackery。也就是说,您要么需要对视图控制器的引用,要么从导航控制器中获取它。见代码编辑 我认为它在 Swift 3 中可能有点不同,当我尝试骇客方法时,它需要一个towardsViewController
参数。我试图将您的代码插入到正确的语法中,例如presenter.unwind(for: UIStoryboardSegue(identifier: String(describing: self), source: self, destination: presenter), towardsViewController: presenter)
,但遇到了崩溃【参考方案2】:
基本上,您需要在此模式视图中创建一个委托。 假设您有 ParentViewController 来创建这个模态视图控制器。 ParentViewController 必须实现委托方法,比如retrieveData(someData)。
在模态视图控制器上,您可以使用方法viewWillDisappear()来触发您要传递给父级的数据的委托方法:
delegate.retrieveData(someData)
如果您在理解如何实现委托时遇到问题,可以查看this link
【讨论】:
谢谢 Joan 我现在正在尝试 - 我应该在父视图控制器 (ProductController) 或模态控制器 (AddProductController) 中创建协议? 我想将handleSave
中收集的数据传递给父级(ProductController),我可以传递整个函数吗?我的印象是handleSave
将用户输入的数据传递到核心数据中,然后 ProductController 正在从核心数据中读取
@d0xi45 您必须在 AddProductController 中声明协议,但在 ProductController 中实现它,请查看我之前发布的链接。我不知道你说的传递整个函数是什么意思,它的工作方式与调用任何其他函数一样。以上是关于关闭模式视图但保留数据的主要内容,如果未能解决你的问题,请参考以下文章
lumen 开启调试模式,关闭debug输出,只保留数据验证提示