我已经构建了一个基本的媒体播放器应用。 我有一个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))
}
答案 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