我读过这个主题:Swift访问闭包中的类变量。但对我没有帮助。
问题
我有一个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
}
}
如果您需要在闭包中使用全局变量/方法,请将self.
放在变量/方法之前
所以你可以更换这个
saleOrder = saleEdited
带有
self.saleOrder = saleEdited
但问题似乎也在其他地方。您只需要将saleOrder从第一个ViewController传递到第二个ViewController,在那里您可以编辑它,然后将数据传递回第一个ViewController
因此,首先从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
方法,即可设置用户从ViewControllerEdit
调用funcReturn
时应执行的操作
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
}
}
}
}
您必须在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
}
}
}
}
出于安全原因,如果saleOrder
是nil
,我建议也实施shouldPerformSegue
来抑制segue
func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
return saleOrderToEdit != nil
}
注意:请不要在Swift 中使用丑陋的objective-c-ishcopy()