TableView 单元格中的 MVVM
Posted
技术标签:
【中文标题】TableView 单元格中的 MVVM【英文标题】:MVVM in TableView Cell 【发布时间】:2021-05-25 07:57:06 【问题描述】:希望你一切都好,我正在开发一个应用程序,它使用 TableView 向使用 ViewModel 的用户显示提要,我的 ViewModel 包含一个包含所有单元格数据的变量,ViewModel 还包含其他数据,我在做什么正在将整个 ViewModel 引用和 indexPath 传递给单元格,您可以在这里看到:
func configureCell(feedsViewModelObj feedsViewModel: FeedsViewModel, cellIndexPath: IndexPath, presentingVC: UIViewController)
//Assigning on global variables
self.feedsViewModel = feedsViewModel
self.cellIndexPath = cellIndexPath
self.presentingVC = presentingVC
let postData = feedsViewModel.feedsData!.data[cellIndexPath.row]
//Populate
nameLabel.text = postData.userDetails.name
userImageView.sd_setImage(with: URL(string: postData.userDetails.photo), placeholderImage: UIImage(named: "profile-image-placeholder"))
updateTimeAgo()
postTextLabel.text = postData.description
upvoteBtn.setTitle(postData.totalBull.toString(), for: .normal)
upvoteBtn.setSelected(selected: postData.isClickedBull, isAnimated: false)
downvoteBtn.setSelected(selected: postData.isClickedBear, isAnimated: false)
downvoteBtn.setTitle(postData.totalBear.toString(), for: .normal)
commentbtn.setTitle(postData.totalComments.toString(), for: .normal)
optionsBtn.isHidden = !(postData.canEdit && postData.canDelete)
populateMedia(mediaData: postData.files)
那么,将完整的 ViewModel 引用和索引传递给单元格然后每个单元格从数据数组访问其数据是正确还是好方法? (如果没有请指导我)。 非常感谢。
【问题讨论】:
我会搜索“MVVM Swift viewModel”,看看其他人是如何做到的。 【参考方案1】:*不需要将整个 ViewModel 引用和 indexPath 传递给单元格。收到数据后回调:
ViewController -> ViewModel -> TableViewDatasource -> TableViewCell.*
视图控制器
class ViewController: UIViewController
var viewModel: ViewModel?
override func viewDidLoad()
super.viewDidLoad()
TaxiDetailsViewModelCall()
func TaxiDetailsViewModelCall()
viewModel = ViewModel()
viewModel?.fetchFeedsData(completion:
self?.tableViewDatasource = TableViewDatasource(_feedsData:modelview?.feedsData ?? [FeedsData]())
DispatchQueue.main.async
self.tableView.dataSource = self.tableViewDatasource
self.tableView.reloadData()
)
查看模型
class ViewModel
var feedsData = [FeedsData]()
func fetchFeedsData(completion: () -> ())
let _manager = NetworkManager()
_manager.networkRequest(_url: url, _modelType: FeedsData.self, _sucessData: data in
self.feedsData.accept(data)
completion()
)
TableView 数据源
class TableViewDatasource: NSObject,UITableViewDataSource
var feedsData: [FeedsData]?
init(_feedsData: [FeedsData])
feedsData = _feedsData
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return feedsData.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
guard let cell = tableView.dequeueReusableCell(withReuseIdentifier: "TableViewCellName", for: indexPath) as? TableViewViewCell else
return TableViewViewCell()
cell.initialiseOutlet(_feedsData: feedsData[indexPath.row])
return cell
表格视图单元格
class TableViewCell: UITableViewCell
@IBOutlet weak var nameLabel : UILabel!
@IBOutlet weak var userImageView : UIImageView!
@IBOutlet weak var postTextLabel : UILabel!
@IBOutlet weak var upvoteBtn : UIButton!
@IBOutlet weak var downvoteBtn : UIButton!
@IBOutlet weak var commentbtn : UIButton!
@IBOutlet weak var optionsBtn : UIButton!
override func awakeFromNib()
super.awakeFromNib()
/*
Passing feedsData Object from TableViewDatasource
*/
func initialiseOutlet(_feedsData: feedsData)
nameLabel.text = _feedsData.userDetails.name
userImageView.sd_setImage(with: URL(string: _feedsData.userDetails.photo), placeholderImage: UIImage(named: "profile-image-placeholder"))
updateTimeAgo()
postTextLabel.text = _feedsData.description
upvoteBtn.setTitle(_feedsData.totalBull.toString(), for: .normal)
upvoteBtn.setSelected(selected: _feedsData.isClickedBull, isAnimated: false)
downvoteBtn.setSelected(selected: _feedsData.isClickedBear, isAnimated: false)
downvoteBtn.setTitle(_feedsData.totalBear.toString(), for: .normal)
commentbtn.setTitle(_feedsData.totalComments.toString(), for: .normal)
optionsBtn.isHidden = !(_feedsData.canEdit && postData.canDelete)
【讨论】:
但是这样我们的cell(view)是直接和model通信的,是不是违反了mvvm规则? 模型视图属性被传递给 TableViewDatasource。单元格(视图)不直接与模型通信。请找到代码 sn-p-TableViewDatasource(_feedsData:modelview?.feedsData ?? [FeedsData]())。以上是关于TableView 单元格中的 MVVM的主要内容,如果未能解决你的问题,请参考以下文章
Swift:Tableview 中特定单元格中的 addSublayer 不是每个单元格
如何在可重用的 tableView 单元格中更新 UITextfield 中的文本值,每个单元格中的值不同
尝试快速从数组中删除时,不应删除 tableview 单元格中的最后一个单元格