简体   繁体   中英

Xcode6 swift UIButton sender not unique?

I'm just wondering why the sender of the UIButton isn't unique or changing. I have a dynamic filled tableview (about 100 rows) with a button in each cell. All buttons have dynamic and therefore different tag id's. In the click event function I'd like to change the button and do some other stuff.

If I use the button sender to identify the button for eg changing the color it changes also one other button in the list.

It seems that the sender are changing while scrolling. All weird.

Sorry for being stupid. I assume there is some obvious stuff I'm missing.

func followButtonTapped(sender: UIButton) {
    println(sender)
    println("UserID: \(sender.tag)")
    sender.enabled = false
    sender.backgroundColor = UIColor.grayColor()
    sender.setTitle("...", forState: UIControlState.Normal)
}

Here an example sender:

<UIButton: 0x7fe5249bacd0; frame = (297 17; 63 24); opaque = NO; autoresize = RM+BM; tag = 1147; layer = <CALayer: 0x7fe5249c2b10>>
UserID: 1147

Here my cellForRowAtIndexPath

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{

    tableView.tableFooterView = UIView(frame: CGRectZero)
    tableView.estimatedRowHeight = 58

    var cell : followCell! = tableView.dequeueReusableCellWithIdentifier(followCellIdentifier) as followCell!

    if(cell == nil){
        cell = NSBundle.mainBundle().loadNibNamed(followCellIdentifier, owner: self, options: nil)[0] as followCell;
    }

    cell?.followName?.text=self.maintext[indexPath.row]
    cell?.followSubtext?.text = self.subtext[indexPath.row]
    cell?.followButton?.addTarget(self, action: "followButtonTapped:", forControlEvents: .TouchUpInside)
    cell?.followButton?.tag = self.UserIds[indexPath.row].toInt()!

    var image = UIImage(named: "default_avatar_40.jpg")

    var imgURL: NSURL = NSURL(string: self.images[indexPath.row])!
    let request: NSURLRequest = NSURLRequest(URL: imgURL)
    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
        if error == nil {
            var image = UIImage(data: data)

            if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) as? followCell {
                cellToUpdate.followImage.image = image
            }
        }
    })

    cell?.backgroundColor = UIColor.clearColor()

    return cell as followCell
}

I believe the behavior you are observing is due to the reuse of tableView cells. When you touch a button and then change its color, the cell that contains that button is only associated with that table row until it scrolls off screen. The cell (and button) will be reused for another row that is coming on screen. If you don't set the color back in cellForRowAtIndexPath the cell coming on screen might get a used button that has been selected.

To make this work, you need to do 3 things:

  1. Independent of the button, you need to keep track of which buttons have been pressed in your model. For instance, in your view controller class, have an array of booleans that has one entry for each button in your table.

     var selected:[Bool] = Array(count: 100, repeatedValue: false) 
  2. In cellForRowAtIndexPath , set up the button based upon your array of booleans in your model.

    To know which row a button is associated with, you can set the button's tag to indexPath.row in cellForRowAtIndexPath and then access the sender.tag in followButtonTapped .

     cell.button.tag = indexPath.row if selected[indexPath.row] { cell.button.enabled = false cell.button.backgroundColor = UIColor.grayColor() } else { cell.button.enabled = true cell.button.backgroundColor = UIColor.whiteColor() } 
  3. In followButtonTapped change the boolean in the array that corresponds to the button you are selecting.

     func followButtonTapped(sender: UIButton) { let row = sender.tag selected[row] = true println(sender) println("UserID: \\(sender.tag)") sender.enabled = false sender.backgroundColor = UIColor.grayColor() sender.setTitle("...", forState: UIControlState.Normal) } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM