滚动时UITableview滞后。
我正在尝试实现iOS 6日历中的事件表。
我有UITableView 500行(事件)。 当我开始滚动动画是顺利的。
但是在两百行开始后滞后。 在原生iOS 6日历事件中列出所有工作顺利。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { double begin = CFAbsoluteTimeGetCurrent(); if(!self.isNoResults) { NSString *cellIdentifier = [NSString stringWithFormat: @"Cell %i %i", indexPath.row, indexPath.section]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; UIImageView *circleImgView; NSString *startTimeStr; NSDateFormatter *formatter; UILabel *timeLbl; UILabel *titleLbl; UILabel *endsLbl; UIImageView *eventTypeImgView; if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; circleImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"newMesIcon.png"]]; circleImgView.frame = CGRectMake(14, 19, 12, 12); [cell.contentView addSubview:circleImgView]; timeLbl = [[UILabel alloc] init]; [timeLbl setBackgroundColor:[UIColor clearColor]]; timeLbl.frame = CGRectMake(35, 15, 200, 20); timeLbl.font = [UIFont systemFontOfSize:13]; timeLbl.tag = 333; [cell.contentView addSubview:timeLbl]; titleLbl = [[UILabel alloc] init]; titleLbl.frame = CGRectMake(123, 15, 200, 20); titleLbl.font = [UIFont fontWithName:@"Arial-BoldMT" size:18]; [titleLbl setBackgroundColor:[UIColor clearColor]]; titleLbl.tag = 444; [cell.contentView addSubview:titleLbl]; [cell.contentView setBackgroundColor:[UIColor colorWithRed:243 / 255.0 green:245 / 255.0 blue:247 / 255.0 alpha:1.0]]; endsLbl = [[UILabel alloc] init]; [endsLbl setBackgroundColor:[UIColor clearColor]]; endsLbl.frame = CGRectMake(49, 11, 40, 8); [endsLbl setFont:[UIFont fontWithName:@"Arial-BoldMT" size:7]]; [endsLbl setTextColor:[UIColor redColor]]; endsLbl.tag = 555; [cell.contentView addSubview:endsLbl]; eventTypeImgView = [[UIImageView alloc] init]; eventTypeImgView.frame = CGRectMake(95, 16, 16, 17); eventTypeImgView.tag = 666; [cell.contentView addSubview:eventTypeImgView]; } startTimeStr = [[self.sortedEventsDict[[[[self.sortedEventsDict allKeys] sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] valueForKey:@"starts"]; formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyy-MM-dd HH:mm"]; NSDate *startDate = [formatter dateFromString:startTimeStr]; NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init]; [timeFormatter setDateFormat:@"HH:mm"]; NSString *timeStr = [timeFormatter stringFromDate:startDate]; NSString *endTimeStr = [[self.sortedEventsDict[[[[self.sortedEventsDict allKeys] sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] valueForKey:@"ends"]; NSDateFormatter *endformatter = [[NSDateFormatter alloc] init]; [endformatter setDateFormat:@"yyy-MM-dd HH:mm"]; NSDate *endDate = [endformatter dateFromString:endTimeStr]; NSDateFormatter *endtimeFormatter = [[NSDateFormatter alloc] init]; [endtimeFormatter setDateFormat:@"HH:mm"]; NSString *endTime = [endtimeFormatter stringFromDate:endDate]; if([[[self.sortedEventsDict[[[[self.sortedEventsDict allKeys] sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] valueForKey:@"type"] isEqualToString:@"event"]) { ((UIImageView *)[cell.contentView viewWithTag:666]).image = [UIImage imageNamed:@"eventsIcon.png"]; } else { ((UIImageView *)[cell.contentView viewWithTag:666]).image = [UIImage imageNamed:@"appointmentsIcon.png"]; } ((UILabel *)[cell.contentView viewWithTag:555]).text = @""; if([timeStr isEqualToString:@"00:00"] && [endTime isEqualToString:@"23:59"]) { timeStr = @"all-day"; } else if([timeStr isEqualToString:@"00:00"] && ![endTime isEqualToString:@"23:59"]) { timeStr = endTime; ((UILabel *)[cell.contentView viewWithTag:555]).text = @"ENDS"; } ((UILabel *)[cell.contentView viewWithTag:333]).text = timeStr; ((UILabel *)[cell.contentView viewWithTag:444]).text = [[self.sortedEventsDict[[[[self.sortedEventsDict allKeys] sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] valueForKey:@"title"]; startDate = nil; timeFormatter = nil; timeStr = nil; endTimeStr = nil; endformatter = nil; endDate = nil; endtimeFormatter = nil; endTime = nil; startTimeStr = nil; formatter = nil; [cell setBackgroundColor:[UIColor colorWithRed:243 / 255.0 green:245 / 255.0 blue:247 / 255.0 alpha:1.0]]; double finish = CFAbsoluteTimeGetCurrent(); NSLog(@"TIME DIFF = %f", finish - begin); return cell; } else { NSString *cellIdentifier = [NSString stringWithFormat: @"Cell No Results %i %i", indexPath.row, indexPath.section]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; if(indexPath.row == 2) { UILabel *noResultsLbl = [[UILabel alloc] init]; noResultsLbl.text = self.noResultsString; [noResultsLbl setFont:[UIFont fontWithName:@"Arial-BoldMT" size:20]]; [noResultsLbl setTextColor:[UIColor colorWithRed:204 / 255.0 green:204 / 255.0 blue:204 / 255.0 alpha:1.0]]; noResultsLbl.frame = CGRectMake(60, 15, 200, 20); noResultsLbl.textAlignment = NSTextAlignmentCenter; [cell.contentView addSubview:noResultsLbl]; } } [cell.contentView setBackgroundColor:[UIColor colorWithRed:243 / 255.0 green:245 / 255.0 blue:247 / 255.0 alpha:1.0]]; cell.userInteractionEnabled = NO; double finish = CFAbsoluteTimeGetCurrent(); NSLog(@"TIME DIFF = %f", finish - begin); return cell; } }
请帮帮我。
你的cellForRowAtIndexPath
长140行,这就是它不能顺利运行的原因。 我建议仔细检查代码并尝试尽可能地重构代码。 格式化程序非常昂贵,而且你可以分配/启动几个。 制作原型或基于xib的单元格,而不是每次都以编程方式设置它。 我还建议不要在视图中使用标签,将其放入xib或原型单元格中并将其作为sockets。
这些更改将加快您的滚动速度。
检查单元格中正在使用的图像的大小。 当图像比他们需要的大时,我曾经遇到过这个问题。 尝试将图像尺寸缩小到适合桌面的最佳尺寸。
您为每个单元格排序所有数据。
if([[[self.sortedEventsDict[[[[self.sortedEventsDict allKeys] sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] valueForKey:@"type"] isEqualToString:@"event"])
尝试为每个[table reloadData]调用使用准备好的数据。 基本上你可以在一个地方执行所有计算,然后只需用结果填充单元格。
找到问题的最好方法是使用Profiler。 它将显示代码的哪一部分在帧之间占用所有cpu。
没有单元重用,几个alloc / init-s和很多NSDateFormatter都非常昂贵
去做:
- 子类UITableViewCell并制作您的自定义单元格
- 使用常量标识符重用单元格
- 使用DFDateFormatterFactory重用
NSDateFormatter
或手动使用格式分隔的NSDateFormatter
,因为每种格式都像一个新的格式化程序
重复使用细胞:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (!cell) { // Setup new cell and constant elements of cell } // Setup data like images, strings and stuff with minimal calculations and formatting return cell; }
我的解决方案可能是一个非常罕见的情况,但它肯定有帮助。
我有一个包含带有一串货币卢布“₽”的标签的单元格(我认为这也可能是由其他货币字符引起的)。 每次重复使用单元格时,此字符串都会动态添加到标签中。 而且表格视图非常迟钝。 然后我只删除了卢布标志,并且滞后消失了。
解决方案:创建一个就绪标签,并将char输入到故事板中的标签中。