Ячейки табличного представления используются повторно - это означает несколько вещей:
- в целом (особенно для вашего случая) вы должны добавлять элементы пользовательского интерфейса только при инициализации ячейки. В противном случае, новые будут добавляться снова и снова.
- вам необходимо хранить информацию о «строках», обычно в вашем источнике данных. В этом примере вам нужен как минимум массив значений Bool, указывающих, должна ли кнопка в строке включаться или нет при повторном использовании ячейки.
Измените класс View Controller на этот:
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
}
}
и измените класс вашей ячейки следующим образом:
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
}
}
Это продемонстрирует использование массива для отслеживания состояния включения Bool для кнопки dropDown в каждой строке. Он также меняет цвет фона кнопки на зеленый, когда включен, и красный, если отключен. Кроме того, он устанавливает заголовок кнопки dropDown, чтобы было легче видеть, какие строки вы просматриваете при прокрутке вверх и вниз.