Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在UITableViewCell中更改以前按下的UIButton标签?_Ios_Xcode_Uitableview_Swift - Fatal编程技术网

Ios 如何在UITableViewCell中更改以前按下的UIButton标签?

Ios 如何在UITableViewCell中更改以前按下的UIButton标签?,ios,xcode,uitableview,swift,Ios,Xcode,Uitableview,Swift,我有带标签的UITableView,还有一个显示音频列表的按钮 一旦按下标有“播放”的按钮,它将变为“停止”并播放音频,如果在其他单元格中按下另一个按钮,则前一个单元格按钮应将其标签变为“播放” 现在,我这里的问题是如何将上一个单元格按钮改回“播放”? 标签是UITableViewCell中的插座,ui按钮以编程方式添加到cellForRowAtIndexPath func tableView(tableView: UITableView, cellForRowAtIndexPath index

我有带标签的
UITableView
,还有一个显示音频列表的按钮

一旦按下标有“播放”的按钮,它将变为“停止”并播放音频,如果在其他单元格中按下另一个按钮,则前一个单元格按钮应将其标签变为“播放”

现在,我这里的问题是如何将上一个单元格按钮改回“播放”?

标签是
UITableViewCell
中的插座,
ui按钮
以编程方式添加到
cellForRowAtIndexPath

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

    let cell = tableView.dequeueReusableCellWithIdentifier("SongTitleCell", forIndexPath: indexPath) as SongsTableViewCell

    let songDic : NSDictionary = arrSongs.objectAtIndex(indexPath.row) as NSDictionary

    cell.lblSongTitle.text = songDic.objectForKey("SongTitle") as? String


    btnPlayPause = UIButton(frame : CGRectMake(13,2,40,40))
    btnPlayPause.tag = indexPath.row
    btnPlayPause.setTitle("Play", forState: UIControlState.Normal)
    btnPlayPause.addTarget(self, action: "cellSongClicked:", forControlEvents: UIControlEvents.TouchUpInside)

    cell.contentView.addSubview(btnPlayPause)

    return cell
}
此处按钮的操作:

func cellSongClicked (sender : AnyObject ){
    var remote = GetSongData()
    remote.delegate = self

    var btnCurrentPressed = sender as UIButton

    //Play Selected Song
    let songDic : NSDictionary = arrSongs.objectAtIndex(btnCurrentPressed.tag) as NSDictionary

    if (btnCurrentPressed.currentTitle == "Play") {

      remote.PlaySelectedSong(songDic.objectForKey("SongURL") as String!)
      btnCurrentPressed.setTitle("Stop", forState: UIControlState.Normal)

    } else {
      playerContoller.stop()
      btnCurrentPressed.setTitle("Play", forState: UIControlState.Normal)
    }

}

谢谢

我会使用以下策略:

1) mantain在类的属性中包含当前播放歌曲的单元格的索引路径(您可以从“cellSongClicked”操作中的UIButton标记知道新的indexPath)

2) 在“cellForRowAtIndexPath”中,根据当前播放歌曲的单元格,将按钮标题设置为“播放”或“停止”

3) 当按下按钮时,刷新当前播放歌曲单元格和新播放歌曲单元格,并调用它们“reloadRowsAtIndexPaths”

希望这有帮助

编辑代码详细信息:

1) 不要每次按下按钮都重新分配。它必须是SongsTableViewCell类的另一个出口(与标签相同)。并从界面生成器中设置目标/操作(在“func cellSongClicked”前面添加@IBAction并从IB中按ctrl键拖动)

2) 将以下属性添加到类中:

private var currentSong : Int?
3) 方法CellForRowatineXpath:

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

    let cell = tableView.dequeueReusableCellWithIdentifier("SongTitleCell", forIndexPath: indexPath) as SongsTableViewCell

    let songDic : NSDictionary = arrSongs.objectAtIndex(indexPath.row) as NSDictionary

    cell.lblSongTitle.text = songDic.objectForKey("SongTitle") as? String
    cell.btnPlayPause.tag = indexPath.row

    var title : String
    if let _currentSong = currentSong {
        title = indexPath.row == _currentSong ? "Stop" : "Play"
    } else {
        title = "Play"
    }
    cell.btnPlayPause.setTitle(title, forState: UIControlState.Normal)

    return cell
}
4) 以及行动:

@IBAction func cellSongClicked (sender : AnyObject ){
    var remote = GetSongData()
    remote.delegate = self

    var btnCurrentPressed = sender as UIButton

    //Play Selected Song
    let songDic : NSDictionary = arrSongs.objectAtIndex(btnCurrentPressed.tag) as NSDictionary

    var rowsToReload = [NSIndexPath]()
    var stopCurrent = false
    if let _currentSong = currentSong {
        if btnCurrentPressed.tag == _currentSong {
            stopCurrent = true
        } else {
            rowsToReload.append(NSIndexPath(forRow: _currentSong, inSection:0))
        }
    }
    rowsToReload.append(NSIndexPath(forRow: btnCurrentPressed.tag, inSection:0))
    currentSong = stopCurrent ? nil : btnCurrentPressed.tag
    self.tableView.reloadRowsAtIndexPaths(rowsToReload, withRowAnimation: .None)
}
编辑:为当前歌曲添加了停止


检查用户是否正在点击当前播放按钮(
如果btnCurrentPressed.tag==\u currentSong
)。在这种情况下,请不要重新加载该行(否则将重新加载两次),并将currentSong属性设置为nil(使用临时布尔stopCurrent)。

谢谢@valfer,我有点困惑,请您调整我的代码,将代码放在何处……我同意,这是最好的解决方案。但是,请注意,您目前正在重复使用您的单元格,并在每次调用CellForRowatineXpath时添加新按钮作为子视图,因此这是您必须注意的事情,尤其是当您走这条路线并强制重新加载时。谢谢@valfer您是一个救生员,非常清晰,工作起来像一个charm@valfer,我现在面临的只是一个小问题。。如果在播放的同一单元格中按“停止”,代码将在以下行中崩溃
self.tableView.reloadRowsAtIndexPaths(rowsToReload,withRowAnimation:.None)
,并出现此错误“尝试为单元格创建两个动画”。解决这个问题的办法是什么?我尝试了很多方法,但都无法解决它。!!ThanksCode在编辑中修改并添加了对它的描述