gpt4 book ai didi

ios - 通知 UITableView dataSource 的变化

转载 作者:行者123 更新时间:2023-11-29 02:09:10 25 4
gpt4 key购买 nike

我的 UITableView 单元格中的数据随时间动态变化,即我为每个单元格“AVMFilmsStore”存储数据的对象自定义类。此类有自己更新数据的方法(每 10 秒从服务器获取进度),例如:

   -(void)getProgress{
// some operations
...

if (progress<100){
[self getProgressWithDelay:10];
}
}

getProgressWithDelay方法是:

-(void)getProgressWithDelay:(float)delay{
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,(int64_t)(delay * NSEC_PER_SEC));

dispatch_after(time,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[self getProgress];
});
}

每次调用此方法后,我都会检查 progress 值是否已更改,我需要使用 UITableView 告诉我的主类它必须重绘进度已更改的每个单元格改变了。我为此自定义了 UITableViewCell 类,其中包含方法:

-(void)styleForReady:(BOOL)isReady andProgress:(float)progress{
if(!isReady){
self.movieDate.hidden = YES;
self.movieName.hidden = YES;
self.playButton.hidden = YES;
self.settingsButton.hidden = YES;
self.progressLabel.hidden = NO;
self.progressLine.hidden = NO;
self.backgroundImage.hidden = YES;
self.progressLine.transform = CGAffineTransformMakeScale(1.0, 4.0);
self.progressLine.progressTintColor = MINT_1_0;
self.progressLabel.textColor = [UIColor blackColor];
self.bgView.hidden = YES;
self.progressLabel.text = NSLocalizedString(@"movieCreating", nil);
[self.progressLine setProgress:progress animated:YES];

} else{
self.movieDate.hidden = NO;
self.movieName.hidden = NO;
self.playButton.hidden = NO;
self.settingsButton.hidden = NO;
self.progressLabel.hidden = YES;
self.progressLine.hidden = YES;
self.backgroundImage.hidden = NO;
self.bgView.hidden = NO;
}

我在 cellForRowAtIndexPath 中调用这个方法,例如:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"readyCell";
AVMMovieCell *cell = [self.readyTable dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

// Configure the cell...
if (cell == nil) {
cell = (AVMMovieCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
}
AVMFilmsStore *oneItem = [readyArray objectAtIndex:indexPath.row];


if (oneItem.ready==1){
[cell styleForReady:YES andProgress:100];
} else { //если идет сборка
[cell styleForReady:NO andProgress:[oneItem getProgress]];

}

return cell;

}

为了使用cellForRowAtIndexPath 通知我的类(class),我在此类的viewDidLoad 方法中注册了NSNotification,然后在getProgress 中发送通知AVMFilmsStore.

当我的主类收到通知时,它会在每个需要的单元格更新中调用 [tableView reloadData]; 方法和 progressView。问题是 progressView 的更新仅在我滚动 UITableView 时发生,尽管数据源已更改。它继续我之前的问题 Check progress where is necessary UITableView我对这个问题很困惑。任何建议都会有帮助。抱歉提出这么愚蠢的问题,但我不知道如何解决。

编辑 这就是我在主类中注册 NSNotifications 的方式:

-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(fsProgressChanged:)
name:@"filmStoreProgressChanged"
object:nil];
}

- (void)fsProgressChanged:(NSNotification *)notification
{

if ([[notification name] isEqualToString:@"filmStoreProgressChanged"]) {
[readyTable reloadData];
}
}

以及我如何在 AVMFilmsStore 中发送通知:我在这个类中有 @property readyProgress,每次我在这个方法中取得进展时,我都会将进度存储到 readyProgress 中,然后我做:

-(void)getProgress{
// some operations
...

if (progress<100){
if(self.readyProgress!=progress){
[[NSNotificationCenter defaultCenter] postNotificationName:@"filmStoreProgressChanged" object:nil];
}
[self getProgressWithDelay:10];
}
}

最佳答案

这里可以使用key-value observing(KVO)方式。首先,您应该在单元格中保留相关 AVMFilmsStore 类的属性/实例。

@property(nonatomic, strong) AVMFilmsStore *filmStore;

然后在单元格的filmStoresetter方法中为属性添加观察者,

- (void)setFilmStore:(AVMFilmsStore *)filmStore {

_filmStore = filmStore;

[_filmStore addObserver:self forKeyPath:@"ready" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

然后实现方法,

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{

if([keyPath isEqualToString:@"ready"])
{
id oldC = [change objectForKey:NSKeyValueChangeOldKey];
id newC = [change objectForKey:NSKeyValueChangeNewKey];

// Handle changes or update cell here
}
}

并在 dealloc 中移除观察者,

- (void)dealloc {

[_filmStore removeObserver:self forKeyPath:@"ready"];
}

在你的viewController中,

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Cell creation

cell.filmStore = [readyArray objectAtIndex:indexPath.row];

return cell;
}

关于ios - 通知 UITableView dataSource 的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29465804/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com