简体   繁体   English

在tableview单元格内单击时更改按钮

[英]change button on click inside tableview cell

I have a tableview cell and in every cell there is like button. 我有一个tableview单元格,每个单元格中都有一个按钮。

I want to make if the user clicks on the like button for the cell, it will change the button image. 我想让用户单击该单元格的“赞”按钮,它将更改按钮图像。

This is my code: 这是我的代码:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Result", forIndexPath: indexPath) as! ResultTableViewCell
    cell.likebutton.tag = indexPath.row
    return cell
}

and the function 和功能

 @IBAction func printTag(sender: AnyObject) {
     let cell = tableView.dequeueReusableCellWithIdentifier("Result", forIndexPath: indexPath) as! ResultTableViewCell

     cell.likebutton.setImage(UIImage(named: "clicklike"), forState: UIControlState.Normal)
 }

Any fix? 可以解决吗?

You should never call dequeueReusableCellWithIdentifier from anywhere except cellForRowAtIndexPath . 除了cellForRowAtIndexPath之外,永远不要从任何地方调用dequeueReusableCellWithIdentifier The flow is: 流程为:

  1. Like Button clicked 点赞按钮
  2. @IBAction handler fires as a result 结果会触发@IBAction处理程序
  3. handler looks up the tag number, updates the model to indicate it's in the 'like' state (the table's backing data -- where's your model? You may not understand how to create and manage one yet.) 处理程序将查找标签号,更新模型以指示其处于“赞”状态(表的支持数据-您的模型在哪里?您可能还不知道如何创建和管理模型。)
  4. handler calls table.reloadRowsAtIndexPaths() with the appropriate NSIndexPath 处理程序使用适当的NSIndexPath调用table.reloadRowsAtIndexPaths()
  5. This propagates into iOS calling cellForRowAtIndexPath on your behalf which then needs to consult your model, notice that that particular row is in the 'liked' state, and render the image within the cell differently, before returning the cell. 这会传播到iOS中, 以您的名义调用cellForRowAtIndexPath ,然后需要查询您的模型,请注意该特定行处于“喜欢”状态,并在返回单元格之前以不同的方式呈现单元格中的图像。

This is probably a lot more than you thought, given your try above. 考虑到上面的尝试,这可能比您想的要多得多。 How actionable is this for you now? 现在这对您有多大作用?

EDIT 编辑

I see you're still looking for shortcuts rather than modeling the data. 我看到您仍在寻找捷径,而不是对数据建模。 You need something like: 您需要类似:

// This is a data model. I'm not sure you understand how critical this is.
var isLikedAtIndex = [ false, false, false ] // Example only: array of 3 booleans

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Result", forIndexPath: indexPath) as! ResultTableViewCell
    if isLikedAtIndex(indexPath.row) {
        cell.likebutton.setImage(someLikedImage)
    }
    else {
        cell.likebutton.setImage(someNotLikedImage)
    }
    cell.likebutton.tag = indexPath.row
    return cell
}


@IBAction func clickLike(sender: UIButton) {
    isLikedAtIndexPath(sender.tag) = true // !! The model !! Save your data!
    let myClickedIndexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
    table.reloadRowsAtIndexPaths([myClickedIndexPath], withRowAnimation: .Automatic)
}

sender should be a reference to likebutton so you should be able to do the following: 发件人应该是likebutton的引用,因此您应该能够执行以下操作:

sender.setImage(UIImage(named: "clicklike"), forState: UIControlState.Normal)

I think that you are going about this the wrong way though. 我认为您的做法是错误的。 When the cell is reused the likebutton will end up being in the wrong state for the new indexPath . 当单元被重用时,对于新的indexPathlikebutton最终将处于错误的状态。 The state of the likebutton should be determined in like按钮的状态应在

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

or 要么

tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)

So, you shouldn't be dequeueing the cell in order to change the button like this. 因此,您不应像这样更改按钮的出队顺序。 Rather, you should be changing the properties that determine the state of the button, and then calling reloadRowsAtIndexPaths(indexPaths: [NSIndexPath], withRowAnimation animation: UITableViewRowAnimation) 相反,您应该更改确定按钮状态的属性,然后调用reloadRowsAtIndexPaths(indexPaths: [NSIndexPath], withRowAnimation animation: UITableViewRowAnimation)

I'm not sure where you're getting the indexPath , but you can determine it using the sender like so: 我不确定在哪里获取indexPath ,但是可以像这样使用发送方来确定它:

let rootViewPoint = sender.superview?.convertPoint(sender.center, toView: self.tableView.center)
let indexPath = self.tableView.indexPathForRowAtPoint(rootViewPoint)

You can then use that indexPath in order to figure out which instance of your model needs to be changed, make the changes, and then call: 然后,可以使用该indexPath来确定需要更改模型的哪个实例,进行更改,然后调用:

self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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