滚动时UITableview滞后。

时间:2013-11-21 15:06:57

标签: ios objective-c uitableview ios6

我正在尝试实现iOS 6日历中的事件表。

我有500行(事件)的UITableView。当我开始滚动动画是顺利的。

但是在两百行开始后滞后。在原生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;
    }
}

请帮助我。

6 个答案:

答案 0 :(得分:7)

你的cellForRowAtIndexPath长140行,这就是它不能顺利运行的原因。我建议仔细阅读代码并尝试尽可能地重构代码。格式化程序非常昂贵,而且你可以分配/启动几个。制作原型或基于xib的单元格,而不是每次都以编程方式设置它。我还建议不要在视图中使用标签,将其放入xib或原型单元格中并将其作为插座。

这些更改将加快您的滚动速度。

答案 1 :(得分:3)

检查单元格中正在使用的图像的大小。当图像大于它们所需的图像时,我遇到过这个问题。尝试将图像尺寸缩小到适合桌面的最佳尺寸。

答案 2 :(得分:2)

您为每个单元格排序所有数据。

if([[[self.sortedEventsDict[[[[self.sortedEventsDict allKeys] sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:indexPath.section]]  objectAtIndex:indexPath.row] valueForKey:@"type"] isEqualToString:@"event"])

尝试为每个[table reloadData]调用使用准备好的数据。基本上你可以在一个地方执行所有计算,然后只用结果填充单元格。

找出问题的最佳方法是使用Profiler。它将显示代码的哪一部分在帧之间占用所有cpu。

答案 3 :(得分:1)

没有单元重用,几个alloc / init-s和很多NSDateFormatter都非常昂贵

TODO:

  1. 子类UITableViewCell并制作自定义单元格
  2. 使用常量标识符重用单元格
  3. 使用DFDateFormatterFactory重复使用NSDateFormatter或手动使用格式分隔的NSDateFormatter,因为每种格式都像新的格式化程序
  4. 重复使用细胞:

    -(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;
    }
    

答案 4 :(得分:1)

我的解决方案可能是一个非常罕见的情况,但它肯定有帮助。

我有一个单元格,其中包含一个带有货币卢布字符串的标签"₽" (我认为这也可能是由其他货币角色引起的)。每次重复使用单元格时,此字符串都会动态添加到标签中。而且表格视图非常迟钝。然后我只删除了卢布标志和滞后消失了。

解决方案:创建一个就绪标签,并将char输入故事板中的标签。

答案 5 :(得分:0)

对我来说,滞后是由主tableView单元格内的另一个tableView引起的(我知道这很奇怪)。我已修复此问题,方法是删除其他tableView并重新考虑应用程序的体系结构,而无需使用“ tableView内置tableView”方法。