连接UITableviewCell与UITableview使用组合重复值



我正在学习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{$0}
.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)
}
}

谢谢你的帮助

要解决重复使用单元格的问题,您必须添加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中,你只需要将publisher添加到cancellable。

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{$0} .sink { index in
print("tap button in cell (index.row)")
}
return cell
}

多个事件(Set)

这里是相同的,但如果你想要有更多的事件,使用集合。

细胞

创建变量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中你只需要存储publisher。

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{$0}
.sink { index in
print("tap button in cell (index.row)")
}.store(in: &cell.cancellables)

return cell
}

祝你好运! !😉

你已经完美地分析和描述了这个问题。所以原因很清楚。查看您的cellForRow实现并思考它的作用:您正在创建并添加新的管道到你的cancellables每次你的cellForRow运行时,不管你是否已经已经为这个单元格的实例化添加了管道。

所以你需要一种不这样做的方法。你能想到一个办法吗?提示:将管道连接到单元格并从那里输出,因此每个单元格只有一个。你的Set不会两次添加相同的管道,因为它是一个Set。

相关内容

  • 没有找到相关文章

最新更新