在UITableViewCell上更新UIProgressView

时间:2011-06-03 14:30:39

标签: tableview uiprogressview

目前,我获得了主要的tableview,其中包含从XML加载并填充的单元格。之后,我可以单击一个单元格并加载一个detailview(xib文件,通过主tableview中的代码加载)。在详细视图上,我可以单击下载按钮,并将一些文件异步下载到文档文件夹。然后我将视图向下弹出,然后再次看到我的桌面视图。

我现在的想法是在tableview单元格中查看下载的进度。我在每个单元格上设置了一个uiprogressview,默认情况下是隐藏的。我现在想在开始下载时看到进度条。我怎样才能做到这一点?

我尝试使用performSelectorOnMainThread和一个选择器,它改变了我所选单元格的进度(我在主tableview中指定)。似乎是一个坏主意 - 没有工作。

有些想法如何做到这一点?


EDIT2:我的解决方案的一些代码,注意!这不是真正的代码,我删除了很多插入这里的行。没有所有版本等我认为解决方案真的很脏,但我没有为我找到更好的解决方案......

一些重要的事情:

  • cellDownloading:知道的数组 正在下载的每个单元格
  • progressDictionary:了解每个单元格的进度
  • cellDictionary:知道每个单元格,填充在tableview的cellsForRowAtIndexpath委托中

我也无法复制整个代码,因为有很多与整个过程无关,但我给你重要的步骤。 我的单元格是通过解析xml创建的,所以每个单元格在我的情况下都有一个setId。

////////////////// // Downloader.mm //////////////////

下载异步的方法

-(void)startAsynchronousDownload:(NSString*)path{    

// generate notification
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
NSNumber *tmpSetId = [NSNumber numberWithInteger:setId];

[userInfo setObject:tmpSetId forKey:@"setId"];

NSNotification* notification = [NSNotification notificationWithName:@"downloadStackNotification" object:self userInfo:userInfo];  
[[NSNotificationCenter defaultCenter] postNotification:notification];  

// add some infos...
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:tmpSetId forKey:@"setId"];
// perhaps more here

// asynchronous download handling
NSOperationQueue *queue = [NSOperationQueue alloc] init];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImagesWithDictionary:) object:dictionary];

// release
[operation release];
[dictionary release];
[userInfo release];
}

在我的示例中,选择器downloadImagesWithDictionary下载了一些图像,对于每个下载的图像,我发送通知。在我的情况下,每堆图像都有一个setId。

[...]
    NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
    NSNumber *sliceCounter = [NSNumber numberWithInt:i];
    NSNumber *amount = [NSNumber numberWithInt:amountOfImages];
    NSNumber *tmpSetId = [NSNumber numberWithInteger:setId];

    [userInfo setObject:sliceCounter forKey:@"actualImage"];
    [userInfo setObject:amount forKey:@"allImages"];
    [userInfo setObject:tmpSetId forKey:@"setId"];
    NSNotification* notification = [NSNotification notificationWithName:@"downloadSliceNotification" object:self userInfo:userInfo];  
    [[NSNotificationCenter defaultCenter] postNotification:notification ];  
[...]

//////////////////////////// // TableViewController.mm ////////////////////////////

现在我们需要获取通知来更新我们的tableview

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadSliceNotification:) name:@"downloadSliceNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadStackNotification:) name:@"downloadStackNotification" object:nil];

我们需要一个单元字典来了解现有tableview单元格的所有索引路径。 将它们填入cellForRowAtIndexPath委托

[cellDictionary setObject:indexPath forKey:[NSString stringWithFormat:@"%d",cellSetId]];

现在我们创建处理程序,以便在收到通知时执行操作 如果下载开始,首先是处理程序 我有一个进度字典,它知道每个单元格的每个进度 我可以通过setId识别每个单元格 - 也许你必须稍微改变一下

- (void)downloadStackNotification:(NSNotification*)notification {  
NSDictionary *userInfo = [notification userInfo];
NSNumber *setId = [userInfo objectForKey:@"setId"];

NSNumber *progress = [NSNumber numberWithInt:0];    
[progressDictionary setObject:progress forKey:[setId stringValue]];

// add cell to downloadlist
[cellDownloading addObject:[setId stringValue]];

}

现在每个下载步骤(在我的情况下是一个图像)。 计算过程并更新字典,让单元格更新进度

- (void)downloadSliceNotification:(NSNotification*)notification {  
NSDictionary *userInfo = [notification userInfo];
NSNumber *sliceCounter = [userInfo objectForKey:@"actualImage"];
NSNumber *amount = [userInfo objectForKey:@"allImages"]; 
NSNumber *setId = [userInfo objectForKey:@"setId"]; 

NSNumber *progress = [NSNumber numberWithFloat:(100/[amount floatValue])*[sliceCounter floatValue]];      

[progressDictionary setObject:progress forKey:[setId stringValue]];
NSIndexPath* indexPath = [cellDictionary objectForKey:[setId stringValue]];

CustomServerCell* cell = (CustomServerCell*)[self.tableView cellForRowAtIndexPath:indexPath];
NSMutableDictionary *downloadData = [[NSMutableDictionary alloc] init];
[downloadData setObject:cell forKey:@"cell"];
[downloadData setObject:sliceCounter forKey:@"actualImage"];
[downloadData setObject:amount forKey:@"allImages"];

[self performSelectorOnMainThread:@selector(updateProgressWithDictionary:) withObject:downloadData waitUntilDone:NO];
} 

更新单元格

-(void)updateProgressWithDictionary:(NSMutableDictionary*)downloadData {

CustomServerCell* cell = (CustomServerCell*)[downloadData objectForKey:@"cell"];
NSNumber *sliceCounter = [downloadData objectForKey:@"actualImage"];
NSNumber *amount = [downloadData objectForKey:@"allImages"];

cell.progressView.hidden = FALSE;
NSNumber *tmpProgress = [progressDictionary objectForKey:[NSString stringWithFormat:@"%d",cell.progressView.tag]];
cell.progressView.progress = [tmpProgress floatValue]/100;
cell.statusLabel.text = [NSString stringWithFormat:@"download slice %d / %d",[sliceCounter integerValue],[amount integerValue]];

}

2 个答案:

答案 0 :(得分:0)

尝试使用

[self performSelectorOnMainThread:@selector(updateProgressBar:) withObject: [NSNumber numberWithFloat:pr] waitUntilDone: YES] 

而不是

progressView.progress += 0.1; // or any other number for that matter 

答案 1 :(得分:0)

我知道了问题。因为我使用通过互联网从XML读取的tableviewcells,我在重新加载tableview时遇到了一些问题。我知道以下成功的过程:

  1. 为每个人创建通知 下载步骤(在我的情况下,我 每片下载切片)
  2. 在主要注册观察员 tableview类
  3. 创建处理程序 通知
  4. 发送 下载信息为userinfo 通知中的字典
  5. 保存每次下载的进度 在带有字典的字典中排序 识别为密钥(在我的情况下是一个集合ID)
  6. 创建一个选择器并读出 字典并设置过程 在右边的单元格
  7. 将选择器添加到performSelectorOnMainThread
  8. 不知道这是否是一个好的解决方案 - 但它对我有用。