我阅读了以下主题:Swift accessing class variable inside closures。但是对我没有帮助。
问题
我有一个ViewControllerData
用于显示数据,另外一个ViewControllerEdit
用于编辑数据。我想将对象从ViewControllerData
发送到ViewControllerEdit
,我用performSegue
做到了,但是我无法从ViewControllerEdit
获取编辑后的对象。我想像prepare
函数中的参数一样传递闭包(funcReturnFromEdit)。
class ViewControllerData: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableViewData: UITableView!
var saleOrder : SaleOrder? // THIS! <--------
// In this closure I want take the edited object.
let funcReturnFromEdit = { (saleEdited : SaleOrder) -> () in
self.saleOrder = saleEdited // I can't do this. Error: Value of type '(ViewControllerData) -> () -> (ViewControllerData)' has no member 'saleOrder'
}
....
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
segue.identifier == "segueEditOrder" {
let editVc = segue.destination as! ViewControllerEdit
if saleOrder != nil {
editVc.saleOrderToEdit = saleOrder!.copy() as! SaleOrder
}
editVc.funcReturn = self.funcReturnFromEdit // <-- Not works
}
}
错误是:Instance member 'saleOrder' cannot be used on type 'ViewControllerData '
此外,我不知道如何在ViewControllerEdit
上创建此功能
class ViewControllerEdit: UIViewController, UITableViewDelegate, UITableViewDataSource {
var saleOrderToEdit : SaleOrder?
var funcReturn = { (SaleOrder) -> Void in {} } // <- This not compile. How to do this?
...
/*
Funcs to make edition...
*/
func endEditions() {
funcReturn(saleOrderToEdit) // <- Here I want send to back ViewControllerData
}
}
答案 0 :(得分:2)
如果需要在闭包中使用全局变量/方法,请将self.
放在变量/方法之前
因此您可以替换
saleOrder = saleEdited
使用
self.saleOrder = saleEdited
,但看起来问题也出在其他地方。您只需要将saleOrder从第一个传递到第二个ViewController,然后在其中进行编辑,然后将数据传递回第一个View Controller
因此,首先从ViewControllerData中删除不必要的代码:
let funcReturnFromEdit = { (saleEdited : SaleOrder) -> () in
saleOrder = saleEdited // I can't do this.
}
并在ViewControllerEdit
替换中修复完成处理程序
var funcReturn = { (SaleOrder) -> Void in {} }
与
var funcReturn : ((SaleOrder) -> ())?
还可以编辑endEditions方法,因为funcReturn是可选的
func endEditions() {
funcReturn?(saleOrderToEdit)
}
现在,您只需在ViewControllerData修复prepare
方法中设置当用户从funcReturn
调用ViewControllerEdit
时应该执行的操作
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueEditOrder" {
let editVc = segue.destination as! ViewControllerEdit
if let saleOrderToPass = saleOrder {
editVc.saleOrderToEdit = saleOrderToPass
editVc.funcReturn = { saleEdited in
self.saleOrder = saleEdited //This code is executed when you call funcReturn?(saleOrderToEdit) from ViewControllerEdit
}
}
}
}
答案 1 :(得分:1)
您必须在ViewControllerEdit
中声明完成关闭并在endEditions
中调用
class ViewControllerEdit: UIViewController, UITableViewDelegate, UITableViewDataSource {
var saleOrderToEdit : SaleOrder!
var editCompletion : ((SaleOrder)->())?
...
func endEditions() {
editCompletion?(saleOrderToEdit)
}
在ViewControllerData
prepare(for
中指定闭包
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueEditOrder" {
let editVc = segue.destination as! ViewControllerEdit
if let saleOrderToEdit = saleOrder {
editVc.saleOrderToEdit = saleOrderToEdit
editVc.editCompletion = { [weak self] saleEdited in
self?.saleOrder = saleEdited
}
}
}
}
出于安全原因,如果shouldPerformSegue
为saleOrder
,我建议也实施nil
来抑制伪装
func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
return saleOrderToEdit != nil
}
注意:请不要在Swift中使用难看的 objective-c-ish copy()