【问题标题】:How to make smooth UITableView in objective-C [closed]如何在objective-C中制作平滑的UITableView [关闭]
【发布时间】:2025-11-21 19:05:02
【问题描述】:

我正在使用 IOS 应用程序。在我的项目中有几个 UITableView 有很多行,每行有两个图像。当我快速滚动时,它无法顺利加载单元格。我怎样才能顺利滚动???

注意:我不想一次加载所有行。
请帮忙
已编辑:
这是我的代码:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

UITableViewCell *cell;
float sca=appDelegate.deviceScaleFloat;
float XOffset=0*sca;

cell = [[UITableViewCell alloc] init];
cell.opaque = YES;

cell.selectionStyle = UITableViewCellSelectionStyleNone;

UIImage *backImg;


backImg= [UIImage imageNamed:[NSString stringWithFormat:@"background-goal-collect%@.png",ipadExtention]];
backImg=[self scaleWithScaleFactor:backImg];

UIImageView *btnBuyImageView=[[UIImageView alloc]initWithImage:backImg];
btnBuyImageView.frame=CGRectMake(XOffset, 0, backImg.size.width, backImg.size.height);
[cell.contentView addSubview: btnBuyImageView];

for (int i=0; i<5 && indexPath.row*5+i<[catFishes count]; i++) {
    int productIndex = (int)indexPath.row*5 + i;
    DBProductAttributes *productAttributes = [allProductAttributes objectAtIndex:productIndex];
    DBProductInfo *productInfo = [catFishes objectAtIndex:productIndex];

    UIImage *frameImage = [UIImage imageNamed:[NSString stringWithFormat:@"background-element-%d%@.png",productAttributes.elementid,ipadExtention]];
    frameImage=[self scaleWithScaleFactor:frameImage];UIImageView *frameView = [[UIImageView alloc] initWithImage:frameImage];

    frameView.frame = CGRectMake((frameImage.size.width*i)+10*sca+5*i*sca, 5*sca , frameImage.size.width, frameImage.size.height);
    frameView.userInteractionEnabled=YES;
    [cell.contentView addSubview:frameView];

    MyTapGestureRecognizer *tapGesture=[[MyTapGestureRecognizer alloc] init];
    tapGesture.tag=productIndex;
    [tapGesture addTarget:self action:@selector(buttonClicked:)];
    [frameView addGestureRecognizer:tapGesture];

    NSString *IconStr = [NSString stringWithFormat:@"i%db.png", productInfo.productid];
    UIImage *btnImg = [UIImage imageNamed:IconStr];

    if(![self isProductPurchesed:productInfo.productid])
    {
        if([ITIWAppDelegate blackimageforstore]>0)
        {     
            btnImg = [self getBlackAndWhiteVersionOfImage:btnImg];               
        }
    }     
    UIImageView *imageIconView;
    imageIconView = [[UIImageView alloc] initWithImage:btnImg];
    imageIconView.frame = CGRectMake(frameView.frame.origin.x+frameImage.size.width-64*sca, frameView.frame.origin.y/*+frameImage.size.height-64*sca*/ , 64*sca, 64*sca);
    imageIconView.opaque = YES;
    [cell.contentView addSubview:imageIconView];

    UILabel *name;
    name = [[UILabel alloc] initWithFrame:CGRectMake(frameView.frame.origin.x, frameView.frame.origin.y+62*sca, frameImage.size.width-0*sca, 18.0f*sca)];
    name.text = productInfo.product_name;
    name.font = [UIFont fontWithName:@"Georgia" size:12.0f*sca];
    name.adjustsFontSizeToFitWidth = YES;
    name.textAlignment = NSTextAlignmentCenter;
    if(![self isProductPurchesed:productInfo.productid])
        name.backgroundColor=[UIColor grayColor];
    else
    name.backgroundColor = [UIColor colorWithRed:colorCodeDragonBook[productAttributes.elementid-1][0]/255.0f green:colorCodeDragonBook[productAttributes.elementid-1][1]/255.0f blue:colorCodeDragonBook[productAttributes.elementid-1][2]/255.0f alpha:1.0f];
    name.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
    //name.shadowColor = [UIColor blackColor];
    name.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
    [cell.contentView addSubview:name];


    NSArray *otherElements = [productAttributes.otherElementid componentsSeparatedByString:@","];
    int k=0;

    UIImage *habitatFlag = [UIImage imageNamed:[NSString stringWithFormat:@"flag-%d.png",productAttributes.elementid]];    UIImageView *habitatFlagView = [[UIImageView alloc] initWithImage:habitatFlag];
    habitatFlagView.frame = CGRectMake(frameView.frame.origin.x-1*sca, frameView.frame.origin.y-1*sca , 15*sca, 22*sca);
    [cell.contentView addSubview:habitatFlagView];
    k+=15;
    for (int i=0; i<[otherElements count]; i++) {
        int otherElementid = [[otherElements objectAtIndex:i] intValue];

        if(otherElementid==productAttributes.elementid) continue;

        UIImage *habitatFlag = [UIImage imageNamed:[NSString stringWithFormat:@"flag-%d.png",otherElementid]];     UIImageView *habitatFlagView = [[UIImageView alloc] initWithImage:habitatFlag];
        habitatFlagView.frame = CGRectMake(frameView.frame.origin.x+k*sca-1*sca, frameView.frame.origin.y-1*sca , 15*sca, 22*sca);
        [cell.contentView addSubview:habitatFlagView];
        k+=15;
    }
}

return cell;
}

当单元格要离开屏幕时会出现问题,tableview 会释放屏幕外的所有单元格。之后我想滚动单元格时重新加载。我认为称重传感器不是最佳选择。但我不知道如何优化它。

【问题讨论】:

  • 检查该单元格是否可见。如果可见,则加载图像,否则将其保留。这样,您将能够加载仅可见单元格(用户正在看到)的图像,并且速度更快。
  • 你能展示你的cellforRowatIndexPath方法吗
  • 你是否使用调度队列来加载图像?
  • 请分享您已有的代码,以便我们为您提供帮助。

标签: ios objective-c uitableview


【解决方案1】:

最好的办法是异步加载图像,而不是在主线程中。

如果需要,可以使用我的 ImageLoader 项目:https://github.com/celian-m/ImageLoader/blob/master/ImageLoader.swift

您所要做的就是使用 CMImageView 而不是 UIImageView。 然后你可以做 [myImageView assignImageFromUrl:YOUR_URL]

这将在后台线程中以 FIFO 模式加载您的图像,并将其保存在内存和磁盘缓存中(即:您只需加载每个图像 1 次)。

【讨论】:

  • 我使用的是本地图片,这就是我不需要从 url 下载任何图片的原因。坦克你的回应。
  • 好的,所以问题可能是您正在调整显示图像的大小,并且使用大量 CPU,我建议您调整资源大小或在后台线程中调整图像大小,然后再将其分配给您的uiimageview
【解决方案2】:

您可以使用SDWebImageCache,它会将图片缓存在磁盘中,并且图片的加载会变得更快。

【讨论】:

    【解决方案3】:
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0ul);
    dispatch_async(queue, ^{
        //set image here
    });
    

    在tableview回调中设置图像异步怎么样:

    - (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
    

    请问图片是网页图片还是本地图片?

    【讨论】:

    • 感谢您的回复。我正在使用本地图像。
    • 异步设置图片是否为您解决了问题?请问图像有多大,即近似分辨率? @NirobHasan
    • 每个图像尺寸 164x158 @billyklh