在UITableViewCell中不断更新UISlider

时间:2012-08-30 20:43:44

标签: ios uitableview uislider

我希望将UISlider用作“Audio VU Meter”类型指示器,其中音轨的级别不断更新UISlider的值。我的应用程序中的每个轨道当前都位于UITableViewCell中,VU Meter是单元格内容视图中的一个子视图。一次显示多达12首曲目。

VU表的更新是通过TCP / IP端口进行的,因此一旦我收到新的VU级别并设置推子值(mySlider.value = newValue)。但是,我可以立即更新滑块的唯一方法是调用performSelectorOnMainThread:@selector(reloadData) withObject:myTableView waitUntilDone:NO。好像我不应该重新加载整个表的数据。

代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    TrackTableCell *cell = (TrackTableCell *)[tableView dequeueReusableCellWithIdentifier:@"TrackTableCell"];

    if(cell == nil)
    {
        [[NSBundle mainBundle] loadNibNamed:@"TrackTableCell" owner:self options:nil];
        cell = [self trackTableCell];

        /**************************/
        /********* FADER  *********/
        /**************************/
        VolumeSlider *fader = [[VolumeSlider alloc] initWithFrame:CGRectMake(0, 0, 265, 30)];
        [fader setRotatedThumbImage:[UIImage imageNamed:@"FaderCap.png"]];
        [fader setRotatedMinTrackImage:[UIImage imageNamed:@"VolumeSlider.png"]];
        [fader setRotatedMaxTrackImage:[UIImage imageNamed:@"VolumeSlider.png"]];

        [fader addTarget:self action:@selector(volumeFaderSliderAction:) forControlEvents:UIControlEventValueChanged];

        fader.value = 0;

        // rotate the slider
        fader.transform = CGAffineTransformMakeRotation(-M_PI_2);
        [cell.contentView addSubview:fader];

        fader.bounds = CGRectMake(0, 0, 265, 30);
        fader.center = CGPointMake(70, 515);

        // property of the cell
        cell.volumeSlider = fader;
    }


    // set the slider to 0
    cell.volumeSlider.value = [[self.tracks objectAtIndex:indexPath.row] volume];

    return cell;
}

通过数据模型([[tracks objectAtIndex:trackNumber] volume])已更新的通知调用以下方法。

- (void) updateVolumeFader:(NSNotification *)note
{
    NSDictionary *extraInfo = [note userInfo];
    int trackNumber = [[extraInfo objectForKey:@"trackNumber"] intValue];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:trackNumber inSection:0];

    TrackTableCell *cell = (TrackTableCell *)[self.tracksTableView cellForRowAtIndexPath:indexPath];

    cell.volumeSlider.value = [[tracks objectAtIndex:trackNumber] volume]; 
}

在查看代码时,我的猜测就是我获取单元格指针的方式。我猜测调用cellForRowAtIndexPath不是最好的方法。此外,我刚才意识到调用cellForRowAtIndexPath本身应该将推子更新为tracks数组中的新值。

正如所建议的那样,或许最好保留所有音轨滑块的缓存数组(或者我的所有单元格)。虽然这当然不是最有效的代码,但我仍然不明白为什么它不起作用?

1 个答案:

答案 0 :(得分:1)

如果您的通知未在主线程上通过,则更新滑块的代码将无效。通知方法中的代码没有问题;只需将其放在一个块中并在主线程上执行,或在注册通知时在主线程(操作队列)上注册。