问题描述
我在保存 UITableViewCell
的状态时遇到问题,不知道如何解决.希望有人能帮助我.
I'm facing problem with saving UITableViewCell
's state and can't figure out how to solve it. Hope somebody can help me.
说明:服务器上有一个 API,我从中获取数据,然后将其存储在 NSMutableArray
中.数组的每个对象都包含属性ready
,它可以是1
或0
.所以我用这些数据填充 UITableView
没有问题,但不是每个数据对象都准备好了(即 0),我需要在服务器上获得完成进度,然后在每个单元格中显示它需要它.我在 UITableViewCell
的动态原型中有 UIProgressView
并在获取后设置进度.如果这种未准备好"的对象只有一个,则没有问题.但是如果有很多对象,我无法显示进度,我不明白为什么.
Explanation:There is an API on server and I get data from it and then store it inside NSMutableArray
. Each object of an array contains property ready
which can be 1
or 0
. So I've no problems with populating UITableView
with this data but not every data object is ready (i.e 0) and I need to get progress of completion at server and after that to show it in each cell is need it. I've UIProgressView
in dynamic prototype of UITableViewCell
and set progress after getting. There is no problem if such "not ready" object is only one. But if there are many objects I can't show progress and I don't understand why.
这是我的代码.
cellForRowAtIndexPath 方法:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"readyCell";
AVMMovieCell *cell = [self.readyTable dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = (AVMMovieCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
AVMFilmsStore *oneItem;
oneItem = [readyArray objectAtIndex:indexPath.row];
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row];
if (oneItem.ready==1){
cell.progressLabel.hidden = YES;
cell.progressLine.hidden = YES;
if ([selecedCellsArray containsObject:[NSString stringWithFormat:@"%@",rowNsNum]] )
{
if (![cell.progressLabel.text isEqualToString:@""]&& ![cell.progressLabel.text isEqualToString:@"Success"] && ![cell.progressLabel.text isEqualToString:@"Creating"]){
cell.progressLabel.hidden = NO;
cell.progressLine.hidden = NO;
} else {
cell.progressLabel.hidden = YES;
cell.progressLine.hidden = YES;
}
}
else{
if(!oneItem.isProcessing && !cell.selected){
cell.progressLabel.hidden = YES;
cell.progressLine.hidden = YES;
}
}
} else { //if processing
if (![processingCellsArray containsObject:[NSString stringWithFormat:@"%@",rowNsNum]]){
[processingCellsArray addObject:[NSString stringWithFormat:@"%@",rowNsNum]];
if (!cell.isSelected){
[cell setSelected:YES];
}
cell.progressLabel.hidden = NO;
cell.progressLine.hidden = NO;
NSArray * arrayOfThingsIWantToPassAlong =
[NSArray arrayWithObjects: cell, oneItem, indexPath, nil];
if(!isMaking){
[self performSelector:@selector(getProgress:)
withObject:arrayOfThingsIWantToPassAlong
afterDelay:0];
} else{
[self performSelector:@selector(getProgress:)
withObject:arrayOfThingsIWantToPassAlong
afterDelay:0.5];
}
isMaking = YES;
} else {
if (!cell.isSelected){
[cell setSelected:YES];
}
cell.progressLabel.hidden = NO;
cell.progressLine.hidden = NO;
NSArray * arrayOfThingsIWantToPassAlong =
[NSArray arrayWithObjects: cell, oneItem, indexPath, nil];
if(!isMaking){
[self performSelector:@selector(getProgress:)
withObject:arrayOfThingsIWantToPassAlong
afterDelay:0];
} else{
[self performSelector:@selector(getProgress:)
withObject:arrayOfThingsIWantToPassAlong
afterDelay:0.3];
}
isMaking = YES;
}
}
return cell;
}
和getProgress方法:
-(void)getProgress:(NSArray*)args{
if (progManager == nil && !progStop){
__block AVMFilmsStore * oneItem = args[1];
if(!oneItem.isLocal){
__block AVMMovieCell * cell = args[0];
__block NSIndexPath *indexPath = args[2];
progManager = [AFHTTPRequestOperationManager manager];
__block NSString *token = [defaults objectForKey:@"token"];
__block NSString *header = [NSString stringWithFormat:@"Bearer %@",token];
__block NSDictionary *params = @{@"lang": NSLocalizedString(@"lang",nil),@"project":oneItem.fileId};
__block NSString *oneHundredPercent;
__block NSString *progIsText;
progManager.responseSerializer = [AFJSONResponseSerializer serializer];
[progManager.requestSerializer setValue:header forHTTPHeaderField:@"Authorization"];
if(cell.selected || isMaking) { //if I just check for "cell.selected" is always "NO"
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[progManager POST:@"http://example.com/api/project/get-progress" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([[responseObject objectForKey:@"result"]isEqualToString:@"success"]){
progCreate = [responseObject objectForKey:@"progress"];
oneHundredPercent = @"100";
if ([progCreate intValue]==[oneHundredPercent intValue]){
if([processingCellsArray containsObject:[NSString stringWithFormat:@"%ld",(long)indexPath.row]]){
[processingCellsArray removeObject:[NSString stringWithFormat:@"%ld",(long)indexPath.row]];
[cell setSelected:NO];
}
[readyArray removeAllObjects];
[defaults setObject:@"false" forKey:@"isSomethingInSort"];
isMaking = NO;
[self getReadyMovies:progIsText nameLabel:oneItem.fileName];
} else{
if([progCreate intValue]>=50){
if([progCreate intValue]>=60){
self.navigationController.navigationItem.leftBarButtonItem.enabled = YES;
createMainButton.enabled = YES;
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"gotFiftyNote" object:@"50"];
[cell.progressLine setProgress:[progCreate floatValue]/100 animated:YES];
} else {
[cell.progressLine setProgress:progUploadLimit];
}
progManager = nil;
progManager.responseSerializer = nil;
progManager.requestSerializer = nil;
token = nil;
header = nil;
params = nil;
progIsText = nil;
oneItem = nil;
cell = nil;
indexPath = nil;
isMaking = YES;
progCreate = nil;
oneHundredPercent = nil;
[self getProgress:args];
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(@"Error: %@", error.localizedDescription);
}];
}
}
}
}
任何建议都会对我有所帮助.这个问题让我头疼了两个星期.
Any suggestions will be helpful for me. I've a headache for two weeks with this problem.
推荐答案
我看到了你的代码,但是对于那些大型方法来说有点难以理解.我不会跟踪数组中的处理单元格.每个单元格都有一个对象来表示,这些对象有一个准备好的布尔值和一个进度值,对吧?所以尝试这样的事情:
I see your code but is kind of difficult to follow with those large methods. I wouldn't keep track of the processing cells in an array. Each cell has an object to represent, those object have a bool value of ready and a progress value, right?. So try something like this:
- 确保您的每个单元格都有一个 progressView 作为子视图.
- 您的单元格类应该有一个名为 styleForReady:(bool)isReady andProgress:(nsinteger)progress 的公共方法
- 拨打服务电话,查看是否为每个型号完成.每当该服务调用返回时,您只需更新数组中的模型对象,并在它们获得新的进度值后执行 [self.tableView reloadData].这将触发 numberOfRows(它应该返回 arrayOfObjects.count)和 cellForRowAtIndexPath:(它应该使那个 indexPath 的单元格出列,抓取代表那个单元格的模型,比如 arrayOfObjects[indexPath.row],最后,调用单元格来设置自己的样式基于该模型做 [cell styleForReady:objectModel.ready andProgress:objectModel.progress])
请记住,控制器应该只跟踪模型对象,使单元出列并告诉单元样式传递模型.不要把所有的逻辑都放在控制器里.
Keep in mind that the controller should just keep track of the model objects, dequeue the cell and tell the cell to style passing the model. Don't put all the logic in the controller.
这篇关于在需要 UITableView 的地方检查进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!