Постоянно обновлять UISlider в UITableViewCell

Я ищу использовать 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 ответ

Если ваши уведомления не попадают в основной поток, ваш код для обновления слайдера не будет работать. Код в вашем методе уведомления в противном случае прекрасен; просто поместите его внутри блока и выполните в основном потоке или зарегистрируйтесь в основном потоке (очередь операций), когда вы регистрируетесь для уведомления.

licensed under cc by-sa 3.0 with attribution.