简体   繁体   English

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

[英]How to pass data from UITableViewCell to a class which inheritances NSObject

Im trying to implement MVVM and Im using ViewController to update the UI, and a view-model to create an object and then to store all the properties of that object locally(user-defaults), now I would like to pass the data from a UITableViewCell to that NSObject class and to store it inside the object property.我尝试实现 MVVM 并使用 ViewController 更新 UI,并使用视图模型创建 object,然后在本地存储 object 的所有属性(用户默认值),现在我想从UITableViewCell 到该 NSObject class 并将其存储在 object 属性中。

TableViewCell:表视图单元:

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)
        }
        
       

        
    }
    
    
    
    
}

ViewModel:视图模型:

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
    }
}

A delegate from the view to the model is the wrong approach. model代表是错误的方法。 It cannot work.它不能工作。 There are multiple table view cells and the default initializer AlbumsPickerTableViewCell() creates another new instance of the cell which is never used in the table view.有多个表格视图单元格,默认初始化器AlbumsPickerTableViewCell()创建了另一个从未在表格视图中使用的单元格实例。

The correct approach is a delegate (in Swift a callback closure is preferable) from the table view cell to the view controller passing the data and the index path.正确的方法是从表格视图单元到视图controller传递数据和索引路径的委托(在 Swift 中最好使用回调闭包)。 The controller updates the model at the given index (path). controller在给定索引(路径)处更新model


In AlbumsPickerTableViewCell add a property callbackAlbumsPickerTableViewCell添加属性回调

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

And replace didSelectRow with并将didSelectRow替换为

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

In the view controller in cellForRow assign the closure to callback , replace datasource with the name of the real datasource arraycellForRow中的视图 controller 中将闭包分配给callback ,将datasource替换为真实数据源数组的名称

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

Delete the entire code related to the protocol/delegate.删除与协议/委托相关的整个代码。

And there is no need that the model inherits from NSObject, not even it's supposed to be a class.并且没有必要 model 继承自 NSObject,甚至不应该是 class。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM