Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 单击单元格中的按钮时访问所有单元格_Ios_Swift_Uitableview - Fatal编程技术网

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

Ios 单击单元格中的按钮时访问所有单元格,ios,swift,uitableview,Ios,Swift,Uitableview,我有一个自定义UITableViewCell的UITableView。每个单元格中都有一个按钮,我想在单击一个按钮时使所有按钮都不可点击。很容易访问包含已单击按钮的单元格,但我还需要访问所有其他单元格,以使其按钮不可单击 因此,当在单元格内单击按钮时,我需要遍历所有其他单元格。。。我找到了一种向上遍历层次结构的方法,因此在button action方法中,我向上一层访问UITableView,从那里我可以访问每个单元格,从每个单元格我可以访问它们的按钮并编辑isUserInteractionEn

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

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

class AnswerCell 2:UITableViewCell{
让answerTextButton:UIButton={
让answerButton=UIButton()
answerButton.setTitle(“初始文本”,用于:。正常)
返回应答按钮
}()
重写init(样式:UITableViewCell.CellStyle,reuseIdentifier:String!){
answerTextButton.addTarget(self,action:#选择器(answerClicked),for:.touchUpInside)
}
@objc func应答已单击(发送方:UIButton){
//在这里,我可以轻松访问单击按钮的单元格
//然后使用TABLEVIEW访问其他单元格及其按钮
//但这不是一个好办法
}
正如我所说,我有一个解决方案,但我希望有更好的方法。我在网上找到的所有解决方案都是关于如何访问单击按钮的单元格,但这一个很简单,我需要的是访问其他单元格,如果可能的话,我希望避免在answerClicked()操作方法中这样做,以便代码保持干净


谢谢。

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

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

var indexPathForSelectedButton: IndexPath?
任何时候此更改,请更新
func answerClicked(发件人:ui按钮)
中的索引并重新加载表视图


在at方法的单元格中,检查当前indexPath是否与存储的相同,如果是,则启用按钮,如果不是,则禁用。我不确定您为什么需要遍历层次结构,特别是更改屏幕上现有单元格的特征

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

var indexPathForSelectedButton: IndexPath?
任何时候此更改,请更新
func answerClicked(发件人:ui按钮)
中的索引并重新加载表视图


在at方法的单元格中,检查当前indexPath是否与存储的indexPath相同,如果是,则启用按钮,如果不是,则禁用。您可以在custom
UITableViewCell
中创建一个
闭包
,并在
单元格
中按下
按钮时调用它,即

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

    @IBAction func buttonClicked(_ sender: UIButton) {
        handler?()
    }
}
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
}
现在,在
表格视图(u:cellForRowAt:)
方法中设置
闭包
,并使用
visibleCells
属性启用/禁用其他
单元格中的
按钮
,即

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

    @IBAction func buttonClicked(_ sender: UIButton) {
        handler?()
    }
}
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
}

如果您想在重新加载时保持启用/禁用
按钮的状态,则需要将其存储在
模型中
您可以在自定义
UITableViewCell
中创建一个
闭包
,并在
单元格中按下
按钮时调用它,即

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

    @IBAction func buttonClicked(_ sender: UIButton) {
        handler?()
    }
}
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
}
现在,在
表格视图(u:cellForRowAt:)
方法中设置
闭包
,并使用
visibleCells
属性启用/禁用其他
单元格中的
按钮
,即

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

    @IBAction func buttonClicked(_ sender: UIButton) {
        handler?()
    }
}
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
}

如果您想在重新加载时保持启用/禁用
按钮
状态,您需要将其存储在
模型中

,这可以通过使用闭包或委托函数的相对较轻的方法实现。鉴于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?
并调整您的
应答单击(发件人:ui按钮)
以调用委托方法

delegate?.cellButtonChangedState(enabled: sender.isEnabled)
通过添加变量和函数,使ViewController(或其他控制器,如果您分离出tableView委托函数)符合协议,并添加函数实现

var按钮重新启用=真

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
}

这可以通过闭包或委托函数的相对轻量级的方法来实现。鉴于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?
并调整您的
应答单击(发件人:ui按钮)
以调用委托方法

delegate?.cellButtonChangedState(enabled: sender.isEnabled)
通过添加变量和函数,使ViewController(或其他控制器,如果您分离出tableView委托函数)符合协议,并添加函数实现

var按钮重新启用=真

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
}

重新加载整个表视图有点激烈。最好是重新加载可见单元格,甚至直接更新可见单元格中的按钮。@Paulw11不太好,由于重复使用,只有可见单元格才会重新加载。感谢您的回复@Scriptable,我选择了另一个答案,因为我想避免访问表视图rom单元格(我的answerClicked在自定义单元格类中),除非我误解了您的响应。@在这种情况下,可能是我可以编写脚本,但如果您有可变高度的单元格,当tableview需要重新计算offsc时,您可以得到闪烁和跳跃的单元格