swift: button.isUserInteractionEnabled = false stops working when scrolling tableview

北战南征 提交于 2021-01-29 13:45:33

问题


I am using a tableview where the first cell contains two buttons. When the first button is activated, the second should be disabled (you should not be able to press it). It all works fine until I start scrolling down the tableview. If I scroll down as far as possible while still being able to see the buttons in first cell, and I activate the first button, I am still able to press the other one. Other things also stops working, but I guess that it is cause by the same thing. Do you have any idea on what happens? See the gif below to see what is going on

I have uploaded the source code on this link, if you need it

https://github.com/Rawchris/scroll-down

I hope you can help :)


回答1:


Table view cells are reused - which means a couple things:

  • in general (particularly for your case) you should only add UI elements when you initialize the cell. Otherwise, new ones get added over and over and over.
  • you need to maintain "row" information, usually in your data source. In this example, you want at least an array of Bool values indicating whether the button in the row should be enabled or not when the cell is reused.

Change your View Controller class to this:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!

    // this would be replaced with your real data
    // test with 20 rows
    // start with all rows having button enabled
    var buttonStatus: [Bool] = Array(repeating: true, count: 20)

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        //Configure the button
        tableView.delegate = self
        tableView.dataSource = self
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return CGFloat(200)
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return buttonStatus.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as! TableViewCell
        cell.selectionStyle = UITableViewCell.SelectionStyle.none

        cell.setButtonEnabled(buttonStatus[indexPath.row], with: "Row \(indexPath.row)")

        cell.callback = { b in
            // update data source with enabled state of button
            self.buttonStatus[indexPath.row] = b
        }

        return cell

    }
}

and change your cell class to this:

class TableViewCell: UITableViewCell {

    var callback: ((Bool) -> ())?

    var button = DropDownBtn()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }

    func commonInit() -> Void {

        button = DropDownBtn.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
        button.setTitle("Button1", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false

        //Add Button to the View Controller
        self.addSubview(button)

        //button Constraints
        button.leftAnchor.constraint(equalTo: self.centerXAnchor, constant: 30).isActive = true
        button.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        button.widthAnchor.constraint(equalToConstant: 100).isActive = true
        button.heightAnchor.constraint(equalToConstant: 40).isActive = true

        //Set the drop down menu's options
        button.dropView.dropDownOptions = ["Option1", "Option2", "Option3", "Option4"]

        self.clipsToBounds = false
        self.contentView.clipsToBounds=false

    }

    func setButtonEnabled(_ b: Bool, with title: String) {
        button.isUserInteractionEnabled = b
        // update the UI - green enabled, red disabled
        button.backgroundColor = b ? UIColor(red: 0.0, green: 0.6, blue: 0.0, alpha: 1.0) : .red
        // update the title so we can see what row we're on
        button.setTitle(title, for: [])
    }

    @IBAction func deactivate(_ sender: Any) {
        // toggle the enabled property of "button"
        button.isUserInteractionEnabled = !button.isUserInteractionEnabled
        // tell the controller the status changed
        callback?(button.isUserInteractionEnabled)
        // update the UI - green enabled, red disabled
        button.backgroundColor = button.isUserInteractionEnabled ? UIColor(red: 0.0, green: 0.6, blue: 0.0, alpha: 1.0) : .red
    }

}

This will demonstrate using an array to track the Bool enabled state for the dropDown button in each row. It also changes the button's background color to Green when enabled, Red when disabled. And, it sets the Title of the dropDown button to make it easy to see which rows you're looking at when you scroll up and down.



来源:https://stackoverflow.com/questions/61251221/swift-button-isuserinteractionenabled-false-stops-working-when-scrolling-tabl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!