You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发:如何修改UITableViewCell实现ViewModel赋值?该写法是否规范?

Is Using cell.viewModel = articleVM a Best Practice?

Absolutely! Using a dedicated viewModel property on your UITableViewCell is absolutely a best practice—and it’s even more valuable as your cell’s data requirements grow beyond just two labels. Here’s why this approach shines:

  • Separation of Concerns: Your cell’s only job is to display data, not fetch or transform it. The ArticleViewModel already handles all the data formatting (like providing fallback "null" values), so your cell stays focused on UI.
  • Cleaner, More Maintainable Code: Instead of writing multiple lines of label.text = ... in cellForRowAt, you can set everything with a single line. If you later add more UI elements (like a Chinese content label), you only update the cell’s viewModel setter—no changes needed in your view controller.
  • Reusability: If you use this cell in multiple places across your app, you don’t have to duplicate the data-assignment logic everywhere. Just pass the view model, and the cell handles the rest.

How to Implement cell.viewModel = articleVM

Let’s adjust your ArticleTalbeViewCell (note: you have a typo here—should be ArticleTableViewCell!) to support this pattern:

Step 1: Add a ViewModel Property to the Cell

Update your cell class to include a viewModel property with a didSet observer that triggers UI updates:

class ArticleTalbeViewCell: UITableViewCell {
    // Optional: Make these non-optional (safer, since we initialize them in setupUI)
    let titlelabel = UILabel()
    let descriptionLabel = UILabel()
    
    // Add the viewModel property here
    var viewModel: ArticleViewModel? {
        didSet {
            updateUI()
        }
    }
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        titlelabel.numberOfLines = 0
        
        descriptionLabel.numberOfLines = 0
        descriptionLabel.textColor = UIColor.lightGray
        descriptionLabel.setContentHuggingPriority(UILayoutPriority.defaultHigh, for: .vertical)
        
        let staview = UIStackView()
        staview.axis = .vertical
        staview.addArrangedSubview(titlelabel)
        staview.addArrangedSubview(descriptionLabel)
        staview.spacing = 8
        staview.translatesAutoresizingMaskIntoConstraints = false
        
        self.contentView.addSubview(staview)
        NSLayoutConstraint.activate([
            staview.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
            staview.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5),
            staview.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 5),
            staview.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5)
        ])
    }
    
    // Add this method to update UI when the viewModel changes
    private func updateUI() {
        guard let viewModel = viewModel else {
            // Reset UI if viewModel is nil (good for cell reuse)
            titlelabel.text = nil
            descriptionLabel.text = nil
            return
        }
        
        titlelabel.text = viewModel.title
        descriptionLabel.text = viewModel.description
        
        // If you later need to show the `chines` field:
        // chinesLabel.text = viewModel.chines
    }
}

Step 2: Update Your View Controller’s cellForRowAt

Now you can simplify your data assignment to a single line:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ArticleTalbeViewCell else {
        fatalError("ArticleTableViewCell not found")
    }
    let articleVM = self.articleListVM.articleAtIndex(indexPath.row)
    cell.viewModel = articleVM // That's it!
    return cell
}

Optional: Add the chines Property to ArticleViewModel

If you want to display the chines field later, just add it to your view model:

extension ArticleViewModel {
    var chines: String {
        return self.article.chines ?? "null"
    }
}

Then add a chinesLabel to your cell and update the updateUI() method—no changes needed in your view controller!


内容的提问来源于stack exchange,提问作者jiexishede

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:17:44