如何将数据从 UITableViewCell 传递到继承 NSObject 的 class

How to pass data from UITableViewCell to a class which inheritances NSObject

我正在尝试实现 MVVM,我正在使用 ViewController 来更新 UI,并使用视图模型来创建对象,然后在本地存储该对象的所有属性(用户-默认值),现在我想将数据从 UITableViewCell 传递到那个 NSObject class 并将其存储在对象 属性.

表格视图单元格:

import UIKit

protocol AlbumsPickerCellDelegate {
    func didSelectedAlbum(_ selectedAlbum: String)
}



class AlbumsPickerTableViewCell: UITableViewCell {

//    var indexPath: IndexPath!

    @IBOutlet var albumsPicker: UIPickerView!
    

    
    var pickerData = ["Album1", "Album2", "Album3"]
    var albumsPickerCellDelegate:  AlbumsPickerCellDelegate?
    
    var isPickerDown = false
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        self.albumsPicker.delegate = self
        self.albumsPicker.dataSource = self
        
        
        albumsPicker.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            albumsPicker.topAnchor.constraint(equalTo: self.topAnchor),
            albumsPicker.bottomAnchor.constraint(equalTo: self.bottomAnchor),
            albumsPicker.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            albumsPicker.trailingAnchor.constraint(equalTo: self.trailingAnchor),
//            albumsPicker.widthAnchor.constraint(equalToConstant: 100),
//            albumsPicker.heightAnchor.constraint(equalToConstant: 40),
            albumsPicker.heightAnchor.constraint(lessThanOrEqualToConstant: 140),
            albumsPicker.centerXAnchor.constraint(equalTo: self.centerXAnchor),
            albumsPicker.centerYAnchor.constraint(equalTo: self.centerYAnchor)


            
        ])
        
        
        self.preservesSuperviewLayoutMargins = false
        self.separatorInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
        self.layoutMargins = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
    }

    
    
//    class func cellHeight() -> CGFloat {
//        return 162.0
//    }
    
    
}

extension AlbumsPickerTableViewCell: UIPickerViewDelegate, UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1

    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerData.count
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerData[row]
    }
    
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        isPickerDown = true
        
        let selectedAlbumOption = pickerData[row]
        
        if let delegate = albumsPickerCellDelegate {
            delegate.didSelectedAlbum(selectedAlbumOption)
        }
        
       

        
    }
    
    
    
    
}

视图模型:

import Foundation
import UIKit


class FilterViewModel: NSObject, AlbumsPickerCellDelegate {
    
    var albumCell = AlbumsPickerTableViewCell()
    
    //Class vars:
    var selectedActivityByUser: String?
    var selectedPostTypesByUser: [String]?
    var selectedHashTagsByUser: [String]?
    var startDate: Date?
    var endDate: Date?
    var selectedAlbumByUser: String?
    
    //    var userFilter = FilterModel(byActivity: selectedActivityByUser, postType: selectedPostTypesByUser, hashTags: selectedHashTagsByUser, startDate: startDate, endDate: endDate, album: selectedAlbumByUser)
    
    override init() {
        super.init()
        //Sets the delegate as self:
        albumCell.albumsPickerCellDelegate = self
    }
}


//TODO: Pass all the info into FilterViewModel with delegates
extension FilterViewModel {
    
    func didSelectedAlbum(_ selectedAlbum: String) {
        self.selectedAlbumByUser = selectedAlbum
    }
}

viewmodel 的委托是错误的方法。它不能工作。 有多个 table 视图单元格,默认初始化程序 AlbumsPickerTableViewCell() 创建另一个从未在 table 视图中使用的单元格实例。

正确的方法是从 table 视图单元到视图 控制器 传递数据的委托(在 Swift 中最好使用回调闭包)和索引路径。 控制器更新给定索引(路径)处的模型


AlbumsPickerTableViewCell中添加一个属性回调

weak var callback : ((UITableViewCell, String) -> Void)?

并将didSelectRow替换为

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    isPickerDown = true
    
    callback?(self, pickerData[row])        
}

cellForRow中的view controller中,将闭包赋值给callback,将datasource替换为真实数据源数组的名称

cell.callback = { actualCell, album in 
    let actualIndexPath = tableView.indexPath(for: actualCell)!
    self.datasource[actualIndexPath.row].selectedAlbumByUser = album
}

删除与protocol/delegate相关的全部代码。

而且模型没有必要继承自 NSObject,甚至它应该是 class。