假设我们有两个视图控制器,一个带有标签的父级,一个带有表格视图的模态子级。如何使用委派将用户在表视图中的选择传递回父级?
ViewController1:
var delegate: vc2delegate?
override func viewDidLoad {
super.viewDidLoad()
let label.text = ""
}
ViewController2:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
let selections = ["1", "2", "3", "4", "5"]
cell.selections.text = selections[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? Cell {
cell.didSelect(indexPath: indexPath as NSIndexPath)
}
dismiss(animated: true, completion: nil)
}
//wherever end of class is
protocol vc2delegate {
// delegate functions here
}
我什至有正确的方法?我从来没有真正了解过这种模式,我认为这对于我学习iOS至关重要。另一个棘手的警告是,关闭模式视图控制器时,不会调用viewDidLoad()。
看看UIViewController的生命周期docs:ViewDidLoad仅被调用一次。
有很多关于如何执行此操作的指南,只需快速搜索即可。当我添加了一个快速字符串数组时,您将需要更新dataSource逻辑,并且您很有可能会更复杂一些,但是想法仍然相同。
顺便说一句,我使用了vc1 / vc2的命名约定,但我希望您对控制器有更有意义的名称。
在您的代码中,您委托了错误的VC。这是一个简短的示例代码:
class VC1: UIViewController {
let textLabel = UILabel()
// whenever you're presenting the vc2
func presentVC2() {
var vc2 = VC2()
vc2.delegate = self
self.present(vc2, animated: true, completion: nil)
}
}
extension VC1: VC2Delegate {
func updateLabel(withText text: String) {
self.textLabel.text = text
}
}
protocol VC2Delegate: class {
func updateLabel(withText text: String)
}
class VC2: UIViewController {
weak var delegate: VC2Delegate?
let dataSource = ["string 1", "tring 2"]
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let string = dataSource[indexPath.row]
self.delegate?.updateLabel(withText: string)
dismiss(animated: true, completion: nil)
}
}
您还可以使用callback函数从tableview更新标签:
[1)将回调函数声明为您的VC2:
var callback:((String) -> Void)?
[2)在表视图的VC2中的CellForRowAt方法中调用此函数:
let dataSource = ["string 1", "tring 2"]
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let string = dataSource[indexPath.row]
var cell = tableView.dequeueReusableCell(withIdentifier: "yourCell") as! YourCell
//here you can call callback function & pass string to VC1
cell.callback?(dataSource[indexPath.row])
}
[3)现在,您可以在调用VC2的任何地方的VC1中调用回调关闭:
class VC1: UIViewController {
let textLabel = UILabel()
//I'm calling this(presentVC2()) function on ViewDidLoad you can call anywhere you want
func viewDidLoad() {
super.viewDidLoad()
presentVC2()
}
// whenever you're presenting the vc2
func presentVC2() {
var vc2 = VC2()
vc2.callback = { text in
self.textLabel.text = text
}
self.present(vc2, animated: true, completion: nil)
}
}