Button State Activates on Wrong Cells

Button state activates on wrong cells

I think this issue is because of dequeuing your cell twice. you should try;

func like(sender: UIButton){
//your code ...
let cell: FeedTableViewCell = self.tableViewAddress.cellForRowAtIndexPath(indexPath) as! FeedTableViewCell
//Your code ...

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

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.

Sample Image

Button action in custom UITableViewCell affects other cells

This is occurring due to UITableview have reusablecell policy.In order to resolve this issue You need to maintain one array of selected items in cellForRowAtIndexPath method you have to verify weather this button is being hold by selected item array. if yes then apply selection styles otherwise apply normal style to it.

Check below source code for buttonclick:

func GetUpdatesButton(sender: UIButton) 
{
var sen: UIButton = sender
var g : NSIndexPath = NSIndexPath(forRow: sen.tag, inSection: 0)
var t : CustomCell = self.myTableView.cellForRowAtIndexPath(g) as! CustomCell
t.btnGetUpdates.backgroundColor = UIColor.redColor()
self.selectedButtonsArray.addObject(indexpath.row)
}

Below code for applying styles on buttons in CellForRowAtIndexPath:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : CustomCell
cell = tableView.dequeueReusableCellWithIdentifier("CustomCellID", forIndexPath: indexPath) as! CustomCell
cell.strName.text = self.names[indexPath.row]
cell.imgPerson.image = UIImage(named: "\(self.persons[indexPath.row])")!

if(self.selectedButtonsArray.containsObject(indexpath.row)){

cell.btnGetUpdates.backgroundColor = UIColor.redColor()
cell.btnGetUpdates.layer.borderColor = UIColor.darkGrayColor().CGColor
cell.btnGetUpdates.layer.borderWidth = 1
cell.btnGetUpdates.layer.cornerRadius = 5.0

}else{

cell.btnGetUpdates.layer.borderColor = UIColor.darkGrayColor().CGColor
cell.btnGetUpdates.layer.borderWidth = 1
cell.btnGetUpdates.layer.cornerRadius = 5.0

}

cell.btnComment.layer.borderColor = UIColor.darkGrayColor().CGColor
cell.btnComment.layer.borderWidth = 1
cell.btnComment.layer.cornerRadius = 5.0

cell.btnReadMore.layer.borderColor = UIColor.darkGrayColor().CGColor
cell.btnReadMore.layer.borderWidth = 1
cell.btnReadMore.layer.cornerRadius = 5.0

cell.dateMissingPersonPlace.text = self.MissingPeoplePlace[indexPath.row]
cell.dateMissingPersonSince.text = self.MissingPeopleSince[indexPath.row]

cell.btnGetUpdates.tag = indexPath.row
cell.btnGetUpdates.addTarget(self, action: "GetUpdatesButton:",forControlEvents: .TouchUpInside)

return cell

}

I hope this helps to resolve your problem! Thanks.

onClick' event affects state of all components, instead of just one

You are populating your state.cells with the same object so when you change id of one cell object it triggers others. Can you change your constructor like below and try

class Board extends React.Component {
const cell = {
level: 0,
owner: null,
turn: 'red'
};
constructor(props) {
super(props);
this.handleCellClick = this.handleCellClick.bind(this);
this.state = {
cells: Array(resolution * resolution).fill(Object.create(cell))
}


Related Topics



Leave a reply



Submit