[英]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 callback在
AlbumsPickerTableViewCell
添加属性回调
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 array在
cellForRow
中的视图 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.