我按照教程制作了一个 MVVP 模型 tableview
我的 tableViewController 叫做 MyProfileController,看起来像这样:
class MyProfileController: UITableViewController {
fileprivate var viewModel: ProfileViewModel?
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UserInfoCell.self, forCellReuseIdentifier: UserInfoCell.identifier)
viewModel = ProfileViewModel()
tableView.dataSource = self.viewModel
}
}
}
我没有在 MyProfileController 中定义 UITableViewDataSource,而是创建了一个名为 ProfileViewModel 的 View 模型并将其传递给 tableView.dataSource
。 ProfileViewModel 定义如下:
class ProfileViewModel: NSObject {
fileprivate var profile: UserProfile?
var items = [ProfileViewModelItem]()
init() {
super.init()
//...
}
}
extension ProfileViewModel: UITableViewDataSource {
// ...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserInfoCell
cell.userDetailTextView.delegate = self
return cell
}
// ...
}
extension ProfileViewModel: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
print(textView.text)
////////////////
// ERROR HERE //
// tableView.beginUpdates()
// tableView.endUpdates()
////////////////
}
}
我在 cellForRowAt indexPath 方法
中设置了 UITextView 的委托(delegate),这样当用户在 TextView 中键入内容时,将调用 textViewDidChange
委托(delegate)方法。到此为止。问题是我无法从这里更新 tableView。如何更新 MyProfileController 的 tablView?
最佳答案
您可以使用闭包将消息发送到您的 TableView Controller 。
在您的数据源对象中声明一个闭包变量。
class ProfileViewModel: NSObject {
var textViewDidChange: (() -> Void)?
// If you need to send some data to your controller, declare it with type. In your case it's string.
// var textViewDidChange: ((String) -> Void)?
}
像这样将您的消息从您的文本字段委托(delegate)发送到您新创建的变量。
func textViewDidChange(_ textView: UITextView) {
self.textViewDidChange?()
// If you need to send your string, do it like this
// self.textViewDidChange?(textView.text)
}
您可以猜到,您的变量 textViewDidChange
仍然是 nil
,因此没有消息会通过。所以我们现在应该宣布这一点。
在您有权访问数据源的 View Controller 中,设置闭包的值。
class MyProfileController: UITableViewController {
fileprivate var viewModel: ProfileViewModel?
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UserInfoCell.self, forCellReuseIdentifier: UserInfoCell.identifier)
viewModel = ProfileViewModel()
tableView.dataSource = self.viewModel
// Set the closure value here
viewmodel.textViewDidChange = { [unowned self](/* if you are sending data, capture it here, if not leave empty */) in
// Do whatever you like with your table view here.
// [unowned self] could sound tricky. It's whole another subject which isn't in the scope of this question. But of course there are some great answers here about it. Simply put, if you don't use it, you'll create a memory leak.
}
}
}
关于ios - 更新父类(super class)的 TableView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52868305/