问题
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