如果在 TableView didSelectRowAtIndexPath 函数中选择了其他行,如何将图像更改为以前的状态?

Posted

技术标签:

【中文标题】如果在 TableView didSelectRowAtIndexPath 函数中选择了其他行,如何将图像更改为以前的状态?【英文标题】:How to change image to previous state if other row is selected in TableView didSelectRowAtIndexPath function? 【发布时间】:2016-07-15 07:28:04 【问题描述】:

所以我有动态表格视图,每一行都有播放图像。如果我选择行图像将更改为暂停图标。但是如果我选择另一行,我需要先前选择的行上的图像再次具有播放图标。 如何处理这样的功能?

我只有:

     class ViewController: UIViewController 
        var stations = [
        (stationIcon: "rr_icon", stationName: "Radio1", urlString: "http://.._320", isPlaying: false),
        (stationIcon: "mm_icon", stationName: "Record2", urlString: "http://../_320", isPlaying: false),
........]

         func playSelectedStation(indexPath: NSIndexPath) 
        let url = NSURL(string: stations[indexPath.row].urlString)!
        stations[indexPath.row].isPlaying = true
        avPlayer = AVPlayer(URL: url)
        avPlayer.play()
    


    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
            let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! RadioTableViewCell
            cell.playPause.image = stations[indexPath.row].isPlaying ? UIImage(named: "cellPause") : UIImage(named: "cellPlay")
            return cell
        

        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 

            switch indexPath.row 
            playSelectedStation(indexPath)
        tableView.reloadData()

广播电台的变化没有问题,只有播放/暂停图标状态有问题

【问题讨论】:

【参考方案1】:

您可以通过浏览可见单元格并禁用所有单元格中的播放按钮来实现它,除了用户刚刚点击的那个:

class PlayItem 
    // your code
    var isPlaying = false


class RadioTableViewCell: UITableViewCell 

    // your code ....

    func setup(item item: PlayItem) 
        image = item.isPlaying ? UIImage(named: "cellPause") : UIImage(named: "cellPlay")
    

在您的委托中:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! RadioTableViewCell
    let item = items[indexPath.row] // you may think of storing this array in some kind of view model
    cell.setup(item: item)
    return cell


func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    let selectedCell = tableView.cellForRowAtIndexPath(indexPath) as! RadioTableViewCell
    let selectedItem = items[indexPath.row]
    selectedItem.isPlaying = !selectedItem.isPlaying

    for cell in tableView.visibleCells 
        guard let visibleCell = cell as? RadioTableViewCell else  return 
        let path = tableView.indexPathForCell(visibleCell)
        let item = items[path.row]
        item.isPlaying = visibleCell == selectedCell
        visibleCell.setup(item: item)
    

更新:我已更新我的答案以将播放状态存储在项目中。

【讨论】:

试过你的方法,当我点击播放时,所有单元格都显示带有暂停图标的图像 我已经编辑了我的答案,有一个错字。请你再试一次好吗? 太棒了!非常感谢 如果我再次点击同一个单元格,我需要它停止播放并将图标更改为播放怎么办?另一个错误,如果我滚动表格视图某些单元格有暂停状态图标 您必须将状态保留在数据对象中,而不是单元格中。我提供的代码只是展示了如何设置一个单元格的方法。【参考方案2】:

使用 MVC 模式而不是将数据存储在视图对象或全局(视图控制器)范围内。那么你的生活就会轻松很多。

我认为每一行都应该由一个模型对象支持。说:

class PlayItem 
    ....
    var isPlaying = false

然后你的cellForRowAtIndexPath 方法:

let playItem = self.playItemArray[indexPath.row]
cell.imageView.image = playItem.isPlaying ? UIImage("cellPause") : UIImage("cellPlay")

然后在您的didSelectRowAtIndexPath 方法中,更改所选项目isPlaying = true 和所有其他项目isPlaying = false,并调用tableView.reloadData()。表格视图将刷新所有单元格以反映其正确状态。

【讨论】:

同样的问题,所有单元格都显示带有暂停图标的图像。 let playItem = .. 应该是什么? 您有一个数组,其中包含PlayItem 对象作为表视图的模型。然后let playItem = self.playItemArray[indexPath.row] 您建议在我现有的数组字典中添加另一个密钥对? 是的,在每个模型(数组中的字典)中跟踪 isPlaying,而不是在视图控制器中。然后仅更改被点击的行的属性。表格单元格是重复使用的,所以当你滚动时,新出现的单元格将是之前消失的单元格,你需要重新配置它的所有视觉属性。 让我们continue this discussion in chat。

以上是关于如果在 TableView didSelectRowAtIndexPath 函数中选择了其他行,如何将图像更改为以前的状态?的主要内容,如果未能解决你的问题,请参考以下文章

如果在另一个表更新后调用太快,tableView.reloadRows 会闪烁

如果在tableview中选中复选框,如何保存所选数组

iOS tableview上textView在编辑状态时,tableview自动上移的功能

在 tableview 中,如果选择第 1 行第 1 行,那么为啥还要选择第 1 行第 1 部分?

如果集合视图已经存在以执行任务,为啥 Xcode 提供 Tableview [重复]

分组 TableView,使用自定大小的部分标题,重新加载后,如果我向上滚动,tableview 会跳转