如何维护对tableview单元格的引用?

时间:2016-03-27 18:08:23

标签: swift uitableview

我已经构建了一个基本的媒体播放器应用。 我有一个tableView,其中列出了播客。 在行项目中,我列出了播客标题。 我还使用detailTextLabel列出当前播放时间的倒计时。

一切正常,除非我滚动tableView,重新加载单元格,我无法再更新时间。

如何保留对单元格的引用,以便即使在滚动后也可以更新单元格文本?

以下是相关的代码......

var myCell = UITableViewCell()

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell")

    .... cell code

    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    myMP.nowPlayingItem = qryPodcasts.items![indexPath.row]
    if myMP.playbackState != MPMusicPlaybackState.Playing {
       myMP.play()
    }

    // Grab a reference to the selected item
    // for displaying elapsed time
    myCell = tableView.cellForRowAtIndexPath(indexPath)!
}

func startTimer(){
    myTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(View_Podcast_List.updateTimer), userInfo: nil, repeats: true)
}
func stoptimer(){
    myTimer.invalidate()
}
func updateTimer(){
    let nowPlayingItemDuration =  myMP.nowPlayingItem?.valueForProperty(MPMediaItemPropertyPlaybackDuration) as! Double
    let remainingTime = nowPlayingItemDuration - myMP.currentPlaybackTime ;

    myCell.detailTextLabel?.text = CommonFuncs.secondsToTime(Int(remainingTime))
}

3 个答案:

答案 0 :(得分:1)

您可以在计时器回调本身中调用cellForRowAtIndexPath。然后你有两种可能:cellForRowAtIndexPath返回nil,所以它不在屏幕上,所以没什么可做的。或者它返回的不是nil,然后你更新它。

确保在cellForRowAtIndexPath委托方法中设置正确的时间,以防在屏幕上没有行时错过了一些更新。

尝试保留对单元格的引用并不起作用。它可以防止细胞被释放,但它不能防止它被重新用于不同的细胞。

答案 1 :(得分:0)

weak var myCell: UITableViewCell?

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell")

    .... cell code

    if tableView.indexPathForSelectedRow == indexPath {
        myCell = cell;
    }

    return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    myMP.nowPlayingItem = qryPodcasts.items![indexPath.row]
    if myMP.playbackState != MPMusicPlaybackState.Playing {
       myMP.play()
    }

    // Grab a reference to the selected item
    // for displaying elapsed time
    myCell = tableView.cellForRowAtIndexPath(indexPath)!
}

func startTimer(){
    myTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(View_Podcast_List.updateTimer), userInfo: nil, repeats: true)
}
func stoptimer(){
    myTimer.invalidate()
}

func updateTimer(){
    guard myCell != nil else { return }
    let nowPlayingItemDuration =  myMP.nowPlayingItem?.valueForProperty(MPMediaItemPropertyPlaybackDuration) as! Double
    let remainingTime = nowPlayingItemDuration - myMP.currentPlaybackTime ;

    myCell?.detailTextLabel?.text = CommonFuncs.secondsToTime(Int(remainingTime))
}

答案 2 :(得分:-1)

有两种方法可以继续: 第一个是标签方法: 在您的cellForRow中为单元格提供标记:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void reverseString(char* str);
int main()
{
    char str [256];
    strcpy_s(str, "Hello World");
    printf(str);
    reverseString(str);
    return 0;
}
void reverse_String(char* str)
{
    int i, j;
    char temp;
    i=j=temp=0;

    j=strlen(str)-1;
    for (i=0; i<j; i++, j--)
    {
        temp=str[i];
        str[i]=str[j];
        str[j]=temp;
    }
    printf(str);
}

当您选择didSelect中的项目时,将indexPath.row存储在属性中。 现在在updateTimer方法中使用viewWithTag(indexPath.row)提取单元格,它将为您提供单元格,然后更新该单元格上的计时器。

第二种方法: 在选择时,didSelect将indexPath.row存储在属性中。然后在cellForRow中,如果indexPath.row等于didSelect中的select属性,则调用实际返回文本的方法updateTimer(在这种情况下,您可能需要更新方法)

MyCell.tag = indexPath.row