单击单元格中的按钮时访问所有单元格

时间:2019-10-24 10:44:33

标签: ios swift uitableview

我有一个带有自定义UITableViewCell的UITableView。每个单元格中都有一个按钮,当我单击一个按钮时,我想使所有按钮都无法单击。访问包含单击按钮的单元格很容易,但是我还需要访问所有其他单元格以使其按钮不可单击。

因此,当在单元格中单击按钮时,我需要遍历所有其他单元格...我找到了一种遍历层次结构的方法,以便在按钮操作方法中,我向上一层进行访问在UITableView中,我可以从那里访问每个单元格,并且从每个单元格可以访问它们的按钮并编辑isUserInteractionEnabled属性。但是,这似乎不是使单元格访问TableView然后访问所有其他单元格的好习惯。

class AnswerCell2: UITableViewCell {

let answerTextButton: UIButton = {
        let answerButton = UIButton()
        answerButton.setTitle("initial text", for: .normal)
        return answerButton
    }()


override init(style: UITableViewCell.CellStyle, reuseIdentifier: String!) {

       answerTextButton.addTarget(self, action: #selector(answerClicked), for: .touchUpInside)

}

@objc func answerClicked(sender: UIButton) {
// HERE I CAN ACCESS EASILY THE CELL WHERE THE BUTTON WAS CLICKED 
// AND THEN USE THE TABLEVIEW TO ACCESS OTHER CELLS AND THEIR BUTTONS 
// BUT THIS IS NOT A NICE WAY
    }

所以我有一个我说的解决方案,但是我想有一个更好的方法。我在网上找到的所有解决方案都与如何访问单击按钮的单元格有关,但这很简单,我需要访问其他单元格,如果可能的话,我希望避免在answerClicked()操作方法中这样做。以便代码保持干净。

谢谢。

3 个答案:

答案 0 :(得分:0)

我不确定为什么您需要遍历层次结构并特别更改屏幕上现有单元格的特征。

只需存储一个代表所选按钮索引的值。

var indexPathForSelectedButton: IndexPath?

每次更改时,请更新func answerClicked(sender: UIButton)中的索引并重新加载表视图。

在at方法的单元格中,检查当前indexPath是否与存储的索引路径相同,如果启用,则启用按钮,否则禁用

答案 1 :(得分:0)

您可以在自定义closure中创建一个UITableViewCell,并在button中按下cell时调用它,即

class TableViewCell: UITableViewCell {
    @IBOutlet weak var button: UIButton!
    var handler: (()->())?

    @IBAction func buttonClicked(_ sender: UIButton) {
        handler?()
    }
}

现在,在closure方法中设置tableView(_:cellForRowAt:)并使用visibleCells属性在其他{{1}中启用/禁用 buttons },即

cells

如果要在重新加载时保持启用/禁用 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell cell.textLabel?.text = arr[indexPath.row] cell.handler = { if let visibleCells = tableView.visibleCells as? [TableViewCell] { visibleCells.forEach({ $0.button.isEnabled = ($0 === cell) }) } } return cell } 状态,则需要存储在button中。

答案 2 :(得分:0)

这可以通过相对轻量的方法(通过闭包或委托函数)来实现。鉴于tableView已经很繁重,我会稍微喜欢这种方法。

创建一个简单的协议以允许单元格通知viewController

protocol CellStateRespondable {  //I'm sure there are better protocol names than this!
  var buttonsAreEnabled: Bool
  func cellButtonChangedSate(enabled: Bool)
}

将委托变量添加到AnswerCell2类中

weak var delegate: CellStateRespondable?

并修改您的answerClicked(sender: UIButton)以调用委托方法

delegate?.cellButtonChangedState(enabled: sender.isEnabled)

通过添加变量和函数,并添加函数实现,使ViewController(或如果分离tableView委托函数,则为其他控制器)符合协议

var buttonAreEnabled = true

func cellButtonChangedSate(enabled: Bool) {
  buttonsAreEnabled = enabled
  if let visibleCells = tableView.visibleCells as? [AnswerCell2] {
    visibleCells.forEach {
      $0.button.isEnabled = enabled
    }
  }
}

,然后在创建单元格时调整cellForRowAt来设置委托和按钮的状态

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  let cell = //dequeue cell and configure as normal
  cell.delegate. = self
  cell.button.isEnabled = buttonsAreEnabled
  return cell
}
相关问题