ios - 更新父类(super class)的 TableView

标签 ios swift uitableview

我按照教程制作了一个 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/

相关文章:

ios - 在没有 prepareForSegue 的情况下推送到另一个 View Controller

swift - 无法将类型 'String' 的值转换为预期的参数类型

ios - 为什么 9 月的月份会在我的时差方法中增加五个小时?

ios - 在通话工具中屏蔽电话号码

ios - 在代码中使用通用 Int - 在 Core Data iOS 中使用 32 位或 64 位 Int?

iphone - iOS开发: Adding an "Add Friend" button inside my app

ios - 从 'NSPersistentStoreResult' 转换为无关类型 '[entity]' 总是失败

Swift:显示来自 URL 的图像

ios - 从另一个 View 重新加载数据 uitableview

ios - 获取行数但不打印