Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.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 重用的单元格具有上一个单元格的UIView_Ios_Objective C_Cocoa Touch_Uitableview - Fatal编程技术网

Ios 重用的单元格具有上一个单元格的UIView

Ios 重用的单元格具有上一个单元格的UIView,ios,objective-c,cocoa-touch,uitableview,Ios,Objective C,Cocoa Touch,Uitableview,我的视图控制器中有一个tableview,每个tableview单元格都与一个音频文件关联。我使用的自定义tableview单元格内部有UIView。每个单元格的UIView都有一个唯一的UIBezierPath,以蓝色笔划。点击单元格时,didSelectRowForIndexPath开始播放音频文件,蓝色的UIBezierPath将与音频文件进度相关的红色UIBezierPath划过 float progress = playTime/duration; self.redWave.stro

我的视图控制器中有一个
tableview
,每个
tableview单元格都与一个音频文件关联。我使用的自定义tableview单元格内部有
UIView
。每个单元格的UIView都有一个唯一的
UIBezierPath
,以蓝色笔划。点击单元格时,
didSelectRowForIndexPath
开始播放音频文件,蓝色的UIBezierPath将与音频文件进度相关的红色UIBezierPath划过

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;
这很好用。我注意到,当我点击第一个单元格时,音频将开始播放,红色路径将开始被抚摸——这是应该发生的,但如果我在这一过程中向下滚动,我点击的第五个单元格具有相同的UIBezierPath,它也在蓝色路径上抚摸红色路径!很明显,电池正在重复使用。此外,这不仅仅发生在我点击一个单元格时——加载tableview时,默认情况下,前5个单元格的UIBezierPath会复制到下一组5个单元格中。我不知道如何避开这件事。有什么想法吗

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString* identifier = @"audioTableCell";

    OSAudioTableCell *cell = [self.audioTable dequeueReusableCellWithIdentifier:identifier];

    if(cell == nil)
    {
         cell = [[OSAudioTableCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: identifier];

    }

        //Pull data from NSFetchResultsController
        Recording * recording = [self.managedDocument.frc objectAtIndexPath:indexPath];

        cell.waveView.minAmpl = [recording.minAmpl floatValue];

        //UIBezierPath Data
        NSData * pathData = recording.waveData;

        //set path for UIView (waveView is custom UIView class)
        cell.waveView.path = [NSKeyedUnarchiver unarchiveObjectWithData:pathData];
        [cell setImageSize:cell.waveView.bounds.size];

        cell.tag = indexPath.row;

        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        //tableCell textfield 
        NSString * track = @"Track";
        NSInteger row = indexPath.row;
        row = [self.managedDocument.frc.fetchedObjects count] - row;
        track = [track stringByAppendingFormat:@" %li",(long)row];
        cell.trackLabel.text = track;
        [cell.textField setFont:[UIFont fontWithName:@"Raleway-SemiBold" size:12]];
        cell.textField.delegate = self;

        if([recording.trackTitle isEqualToString:@""])
        {
            cell.textField.text = track;
        }
        else
        {
            cell.textField.text = recording.trackTitle;

        }

        UIColor * circleColor = [UIColor colorWithRed:107/255.0f green:212/255.0f blue:231/255.0f alpha:1.0f];

        cell.trackIcon.backgroundColor = circleColor;

        [cell.trackIcon.layer setCornerRadius:cell.trackIcon.bounds.size.width/2];

        cell.trackIcon.layer.masksToBounds = YES;


return cell;
}

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;
didselectRowatingIndexPath
在my
tableViewCell
类中调用以下方法:

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;
-(void) rowSelected2: (NSURL*) url
{

    self.audioPlayer = [OSTablePlayerController getInstance];
    NSData *data=[NSData dataWithContentsOfURL:url];
    [self.audioPlayer playAudio:data];
    self.audioPlayer.isPlayerPlaying = YES;
    self.timer = [NSTimer timerWithTimeInterval:0.01 target:self selector:@selector(updateProgress:) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

 }

表视图旨在重用这些行。这是一项可以提高应用程序性能的功能,尤其是当您的表视图中包含大量元素时

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;
由于表视图重用了它们的行,因此需要在回收行之前手动清除它们。如果通过创建UITableViewCell子类来实现单元格,则可以覆盖其

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;
-(作废)预先准备

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;

方法。每次要重新使用单元格时,都会调用它,这是进行可能需要的任何清理的最佳位置。

许多在tableview单元格中播放媒体的应用程序(例如tumblr)会在单元格滚动时停止播放(可能使用prepareForReuse)

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;
如果要继续播放,则需要将与该播放相关联的所有状态保留在表格单元(在模型中)之外,包括播放进度。您的自定义单元格应准备好指示从任何点(0-99%)开始的播放进度。当一个单元格进入视图时(在您的数据源
cellforrowatinexpath
),您需要检查您的模型,查看该单元格的媒体是否正在播放,并让它绘制当前进度(希望它有一个方法
setProgress:(float)进度
,用于更改进度属性并告知bezier工程视图需要显示

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;

这也意味着,如果设置了一个计时器来检查媒体播放进度,那么它的目标不能是单元格,而是维护模型的视图控制器。

您是否尝试了
dequeueReusableCellWithIdentifier:forIndexPath:
?@mckeejm我尝试了
OSAudioTableCell*单元格=[self.audioTable dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
没有任何区别:(+1我不知道这个
prepareforeuse
方法。我总是在从
返回单元格之前重置单元格-tableView:cellforRowAtIndexPath:
这种方法的问题是,如果我选择一个单元格并在文件仍在播放时向下滚动,然后滚动回我选择的单元格,这将导致红色部分h设置为零,使其看起来好像我从未选择过单元格。具体来说,“任何清理”是什么意思。您能给出任何您希望“清理”的一般示例吗?我遇到了与此问题类似的问题,我不清楚这有什么好处。谢谢。@Brosef Your view controller(或处理单元配置的任何内容)将需要跟踪选定的单元格以及每个音频文件所用的时间。这样,每次选定的单元格出现在屏幕上时,都可以正确地重新绘制红线。@tpdietz假设您的每个表视图单元格都有一个图像视图,并且图像视图显示的图像是从INTERNET。在图像下载之前,您希望显示某种占位符。在这种情况下,您的清理过程可能涉及取消任何正在进行的单元格下载操作,并将其图像视图的图像重置为占位符。我有一个名为
OSTablePlayerController
NSObject
类作为音频播放器及其所有功能(启动、停止)作为属性。但是,我从我的表视图单元格类中分配并初始化它。我的表视图单元格类还具有检测进度的计时器。因此我需要将所有这些移动到我的视图控制器?是的,并将其目标/操作设置到视图控制器。在那里,您需要确定模型中的哪一行正在播放并更新它的进度(模型需要保持播放进度,因为您不能依赖周围的单元格)。知道为什么第二组5个单元格与第一组5个单元格具有相同的UIView路径吗?
float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;