我有一个父级UIViewController
,它具有声明为这样的自己的视图模型
lazy var chatService: ChatService = {
let chatService = ChatService()
return chatService
}()
lazy var viewModel: ChatControllerViewModel = {
let viewModel = ChatControllerViewModel(chatService: chatService)
return viewModel
}()
此视图控制器的UITableView
声明为
lazy var tableView: UITableView = {
let tableView = UITableView(frame: .zero)
return tableView
}()
在viewDidLoad
内部,我有这样的绑定
viewModel.reloadData = { [weak self] in
self?.insertNewMessage()
}
这会触发以下方法
fileprivate func insertNewMessage() {
let indexPath = IndexPath(row: viewModel.history.count - 1, section: 0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .fade)
tableView.endUpdates()
tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
}
这很好用。我还有一个子视图控制器,其类型为UICollectionViewController
,声明为
lazy var chatQuestionsCollectionView: ChatQuestionsController = {
let layout = SnappingCollectionViewLayout()
let cv = ChatQuestionsController(collectionViewLayout: layout)
return cv
}()
此UICollectionViewController
具有自己的视图模型,该视图模型的设置方法与上述相同。
在某种程度上一切都很好;
我的ChatControllerViewModel
调用ChatService并请求最新消息,然后将其从ChatService推送到我的视图模型中
聊天服务
var pushResponse: ((_ response: ChatMessage) -> Void)?
ChatControllerViewModel
init(chatService: ChatService = ChatService()) {
self.chatService = chatService
chatService.pushResponse = { [weak self] response in
self?.chatHistory.append(response)
}
}
这会将新消息推送到我的UITableView
,然后重新加载数据,显示消息。
但是,我的子视图控制器,然后是UICollectionView
也与ChatService
进行了对话-它包含一系列触发响应的水平可滚动按钮。
按下按钮时,我可以通过日志查看,我的聊天服务已被调用,逻辑按预期运行,但是此时聊天服务调用var pushResponse: ((_ response: ChatMessage) -> Void)?
的视图控制器未更新。
我怀疑这是因为我的UICollectionView正在与ChatService
的另一个未建立该绑定的实例进行对话。
听起来合理吗?如果是这样,否定此问题的正确方法是什么?我考虑过使用委托模式,但是不确定应该委托什么以及在哪里进行委托。
在布局中提供一些背景信息:
我有一个垂直显示聊天消息的表格视图。 在该视图的底部,有一个集合视图,其中显示了水平滚动的按钮。
按下这些按钮将调用聊天服务,然后聊天服务将触发与表视图模型的绑定,这将为表视图重新加载新数据。
答案 0 :(得分:1)
您正在集合视图中创建ChatService
的新实例,该实例没有绑定设置。
如果您不想使用Singleton,我将在您的父级大多数组件中创建它的实例,然后通过Dependency Injection传递给它。