使用 Combine repeat values 连接 UITableviewCell 和 UITableview
Connect UITableviewCell with UITableview using Combine repeat values
我正在学习 combine,我想使用 combine 而不是 cell 和 tableview 之间的委托。我已设法连接并接收信息,但问题是当单元格被重复使用时,每次我生成相同的事件时,我收到的次数与以前在该重复使用的单元格中使用的次数一样多。
我已在视图控制器中将可取消项声明为
var cancellables: Set<AnyCancellable> = []
这是 cellForRow 方法
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.celdaReuseIdentifier, for: indexPath)
as? MyCell else {
return MyCell()
}
cell.index = indexPath
cell.lbTitle.text = String("Cell \(indexPath.row)")
cell.tapButton.compactMap{[=11=]}
.sink { index in
print("tap button in cell \(index.row)")
}.store(in: &cancellables)
return cell
}
单元格是
class MyCell: UITableViewCell {
static let cellNibName = "MyCell"
static let celdaReuseIdentifier = "MyCellReuseIdentifier"
@IBOutlet weak var lbTitle: UILabel!
@IBOutlet weak var button: UIButton!
var index: IndexPath?
let tapButton = PassthroughSubject<IndexPath?, Never>()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
@IBAction func tapButton(_ sender: Any) {
self.tapButton.send(index)
}
}
感谢您的帮助
您把问题分析描述的很到位。所以原因很清楚。查看您的 cellForRow
实施并思考它的作用:您正在 创建并添加一个 新 管道 到您的 cancellables
每次你的cellForRow
运行,无论你是否已经为这个单元实例化添加了一个管道。
所以你需要一种不这样做的方法。你能想办法吗?提示:将管道连接到 cell 并从那里出售,因此每个 cell 只有一个 。您的 Set 不会两次添加 相同的 管道,因为它是一个 Set。
要解决重复使用单元格的问题,您必须将 Set 添加到单元格。
如果您只打算在单元格内使用事件,您可以使用单个 AnyCancellable:
单个事件(AnyCancellable)
在 AnyCancellable 类型的单元格中声明一个变量。每次重复使用该单元格时,都会添加一个新的发布者来替换之前的发布者,并且您不会多次收到该事件。
单元格
class MyCell: UITableViewCell {
static let cellNibName = "MyCell"
static let celdaReuseIdentifier = "MyCellReuseIdentifier"
@IBOutlet weak var lbTitle: UILabel!
@IBOutlet weak var button: UIButton!
var index: IndexPath?
// store publisher here
var cancellable: AnyCancellable?
// Single Publisher per cell
let tapButton = PassthroughSubject<IndexPath?, Never>()
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func tapButton(_ sender: Any) {
self.tapButton.send(index)
}
}
ViewController
在 Viewcontroller 中,您只需将发布者添加到可取消项中。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.celdaReuseIdentifier, for: indexPath)
as? MyCell else {
return MyCell()
}
cell.index = indexPath
cell.lbTitle.text = String("Cell \(indexPath.row)")
// Add your publisher to your cancellable and remove store function.
cell.cancellable = cell.tapButton.compactMap{[=11=]} .sink { index in
print("tap button in cell \(index.row)")
}
return cell
}
多个事件(设置 )
这里是一样的,但是使用集合以防你想要更多的事件。
单元格
创建一个变量 Set 来存储发布者。
在这种情况下,在重新使用单元格之前,我们必须在创建新单元格之前删除可取消项。
class MyCell: UITableViewCell {
static let cellNibName = "MyCell"
static let celdaReuseIdentifier = "MyCellReuseIdentifier"
@IBOutlet weak var lbTitle: UILabel!
@IBOutlet weak var button: UIButton!
var cancellables: Set<AnyCancellable>?
var index: IndexPath?
// Multiple Publishers per cell
let tapButton = PassthroughSubject<IndexPath?, Never>()
let tapView = PassthroughSubject<UIImage, Never>()
// Remove all suscriptions before reuse cell
override func prepareForReuse() {
super.prepareForReuse()
cancellables.removeAll()
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
@IBAction func tapButton(_ sender: Any) {
self.tapButton.send(index)
}
}
ViewController
在 Viewcontroller 中,您只需存储发布者。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.celdaReuseIdentifier, for: indexPath)
as? MyCell else {
return MyCell()
}
cell.index = indexPath
cell.lbTitle.text = String("Cell \(indexPath.row)")
// Add your publisher to your cell´s collection of AnyCancellable
cell.tapButton.compactMap{[=13=]}
.sink { index in
print("tap button in cell \(index.row)")
}.store(in: &cell.cancellables)
return cell
}
祝你好运!!
我正在学习 combine,我想使用 combine 而不是 cell 和 tableview 之间的委托。我已设法连接并接收信息,但问题是当单元格被重复使用时,每次我生成相同的事件时,我收到的次数与以前在该重复使用的单元格中使用的次数一样多。
我已在视图控制器中将可取消项声明为
var cancellables: Set<AnyCancellable> = []
这是 cellForRow 方法
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.celdaReuseIdentifier, for: indexPath)
as? MyCell else {
return MyCell()
}
cell.index = indexPath
cell.lbTitle.text = String("Cell \(indexPath.row)")
cell.tapButton.compactMap{[=11=]}
.sink { index in
print("tap button in cell \(index.row)")
}.store(in: &cancellables)
return cell
}
单元格是
class MyCell: UITableViewCell {
static let cellNibName = "MyCell"
static let celdaReuseIdentifier = "MyCellReuseIdentifier"
@IBOutlet weak var lbTitle: UILabel!
@IBOutlet weak var button: UIButton!
var index: IndexPath?
let tapButton = PassthroughSubject<IndexPath?, Never>()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
@IBAction func tapButton(_ sender: Any) {
self.tapButton.send(index)
}
}
感谢您的帮助
您把问题分析描述的很到位。所以原因很清楚。查看您的 cellForRow
实施并思考它的作用:您正在 创建并添加一个 新 管道 到您的 cancellables
每次你的cellForRow
运行,无论你是否已经为这个单元实例化添加了一个管道。
所以你需要一种不这样做的方法。你能想办法吗?提示:将管道连接到 cell 并从那里出售,因此每个 cell 只有一个 。您的 Set 不会两次添加 相同的 管道,因为它是一个 Set。
要解决重复使用单元格的问题,您必须将 Set
如果您只打算在单元格内使用事件,您可以使用单个 AnyCancellable:
单个事件(AnyCancellable)
在 AnyCancellable 类型的单元格中声明一个变量。每次重复使用该单元格时,都会添加一个新的发布者来替换之前的发布者,并且您不会多次收到该事件。
单元格
class MyCell: UITableViewCell { static let cellNibName = "MyCell" static let celdaReuseIdentifier = "MyCellReuseIdentifier" @IBOutlet weak var lbTitle: UILabel! @IBOutlet weak var button: UIButton! var index: IndexPath? // store publisher here var cancellable: AnyCancellable? // Single Publisher per cell let tapButton = PassthroughSubject<IndexPath?, Never>() override func awakeFromNib() { super.awakeFromNib() } @IBAction func tapButton(_ sender: Any) { self.tapButton.send(index) } }
ViewController
在 Viewcontroller 中,您只需将发布者添加到可取消项中。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.celdaReuseIdentifier, for: indexPath)
as? MyCell else {
return MyCell()
}
cell.index = indexPath
cell.lbTitle.text = String("Cell \(indexPath.row)")
// Add your publisher to your cancellable and remove store function.
cell.cancellable = cell.tapButton.compactMap{[=11=]} .sink { index in
print("tap button in cell \(index.row)")
}
return cell
}
多个事件(设置 )
这里是一样的,但是使用集合以防你想要更多的事件。
单元格
创建一个变量 Set
class MyCell: UITableViewCell {
static let cellNibName = "MyCell"
static let celdaReuseIdentifier = "MyCellReuseIdentifier"
@IBOutlet weak var lbTitle: UILabel!
@IBOutlet weak var button: UIButton!
var cancellables: Set<AnyCancellable>?
var index: IndexPath?
// Multiple Publishers per cell
let tapButton = PassthroughSubject<IndexPath?, Never>()
let tapView = PassthroughSubject<UIImage, Never>()
// Remove all suscriptions before reuse cell
override func prepareForReuse() {
super.prepareForReuse()
cancellables.removeAll()
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
@IBAction func tapButton(_ sender: Any) {
self.tapButton.send(index)
}
}
ViewController
在 Viewcontroller 中,您只需存储发布者。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCell.celdaReuseIdentifier, for: indexPath)
as? MyCell else {
return MyCell()
}
cell.index = indexPath
cell.lbTitle.text = String("Cell \(indexPath.row)")
// Add your publisher to your cell´s collection of AnyCancellable
cell.tapButton.compactMap{[=13=]}
.sink { index in
print("tap button in cell \(index.row)")
}.store(in: &cell.cancellables)
return cell
}
祝你好运!!