如何在UITableViewCell中刷新单个按钮而不是刷新整个表格或整个单元格?

时间:2017-02-07 21:01:37

标签: ios swift uitableview swift3

在我的swift应用中,我有UITableView个静态单元格和许多动态单元格。

静态单元格包含不同的字段,例如标签,地图(取自MapKit)和一个按钮,用于指示用户是否已投票。

现在,当用户按下按钮时,我想改变其颜色,可能没有刷新任何其他内容。

到目前为止,我的代码看起来像这样:

var currentUserVote:Int = 0

func tableView(_ tview: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if (indexPath as NSIndexPath).row == 0 {
        let cell = tview.dequeueReusableCell(withIdentifier: "cellStatic") as! VideoDetailsCell

        fetchScore(cell.score)

        let voteUpImage = UIImage(named: "voteUp");
        let tintedVoteUpImage = voteUpImage?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
        cell.voteUpButton.setImage(tintedVoteUpImage, for: UIControlState())

        checkUsersVote() { responseObject in

            if(responseObject == 1) {

                cell.voteUpButton.tintColor = orangeColor

            } else if (responseObject == -1){
                cell.voteUpButton.tintColor = greyColor

            } else {
                cell.voteUpButton.tintColor = greyColor

            } 

            self.currentUserVote = responseObject
        }

        //map handling:
        let regionRadius: CLLocationDistance = 1000

        let initialLocation = CLLocation(latitude: latitude, longitude: longitude)

        centerMapOnLocation(initialLocation, map: cell.mapView, radius: regionRadius)
        //cell.mapView.isScrollEnabled = false
        cell.mapView.delegate = self
        .
        .
        . 
        return cell
        } else {
        //handle dynamic cells
        }
}

因此,在上述方法中,我检查用户是否已经投票,并根据我在按钮上设置不同的颜色。我也将地图集中在特定点上。

现在,由于它是一个静态单元格,我将IBAction插座连接到该按钮:

@IBAction func voteUpButtonAction(_ sender: AnyObject) {
     if(currentUserVote == 1) {
        self.vote(0)
    }else if (currentUserVote == -1){
        self.vote(1)
    } else {
        self.vote(1)
    }
}

vote方法的工作原理如下:

func vote(_ vote: Int){

    let indexPath = IndexPath(row: 0, section: 0)

    let cell = tview.dequeueReusableCell(withIdentifier: "cellStatic") as! VideoDetailsCell


    switch(vote) {
    case 1:
        cell.voteUpButton.tintColor = orangeColor
    case 0:
        cell.voteUpButton.tintColor = greyColor
    case -1:
        cell.voteUpButton.tintColor = greyColor
    default:
        cell.voteUpButton.tintColor = greyColor
    }

    tview.beginUpdates()
    tview.reloadRows(at: [indexPath], with: .automatic)
    tview.endUpdates()

    currentUserVote = vote

    //sending vote to my backend
}

我的问题是,当用户点击按钮时,他调用方法vote,然后 - 根据投票,按钮改变颜色,但在调用方法cellForRow之后立即调用它再次更改按钮的颜色。此外,它还会刷新内部的地图。

我想要实现的是当用户点击按钮时,它应该立即改变它的颜色和它的颜色。地图保持不变,按钮不会再次从cellForRow更改。

是否有办法只刷新该特定按钮而不再调用cellForRow

3 个答案:

答案 0 :(得分:2)

  1. 首先,您会混淆静态和动态细胞。您只能在UITableViewController中使用静态单元格,并且不能同时使用静态和动态单元格。
  2. 我强烈建议您不要使用单元格存储地图和按钮。滚动屏幕后,单元格中的所有元素都将被释放。
  3. 我建议您使用TableViewHeaderView执行此任务。在这种情况下,您可以将按钮和地图视图设置为@IBOutlet

    (查看有关adding tableview headerView的更多信息。您也可以从界面构建器中进行设置。)

    另一种方法是更改​​tableView.contentInset并将地图和按钮设置为tableView的子视图。需要创建Stretchy Headers时使用此方法。

    enter image description here

答案 1 :(得分:0)

应该很简单,只需在按钮处理程序中执行即可。 sender参数中存在导致操作的按钮对象。当你从IB连接它时,有一个下拉菜单选择发件人类型,你可能已经错过了它,并且那里的UIButton类型显然会显而易见。

只需更改您的处理程序:

@IBAction func voteUpButtonAction(_ sender: UIButton) {
     if(currentUserVote == 1) {
        self.vote(0)
    }else if (currentUserVote == -1){
        self.vote(1)
    } else {
        self.vote(1)
    }
    sender.backgroundColor = yourFavouriteColor
}

另一种方法是为您的按钮创建IBOutlet,因为它来自静态单元格,然后您就可以从视图控制器中的任何位置引用它。

答案 2 :(得分:0)

在此电话会议中:

func tableView(_tview:UITableView,cellForRowAt indexPath:IndexPath) - >的UITableViewCell

我看到它调用了checkUsersVote(),我猜测它应该在vote()调用中设置更新值。可能问题是你不是这样做的     currentUserVote =投票 直到调用reloadRows()之后?