【问题标题】:Lazy Loading UIScrollView - how to make scrolling smoother延迟加载 UIScrollView - 如何使滚动更流畅
【发布时间】:2023-04-04 23:47:02
【问题描述】:

我已经在这样的滚动视图中完成了延迟加载:

-(void)scrollViewDidScroll:(UIScrollView *)myScrollView {

    int currentPage = (1 + myScrollView.contentOffset.x / kXItemSpacingIphone);
    for (ItemView* itemView in [self.itemRow subviews]){
        if (itemView.tag >= currentPage-2 && itemView.tag <= currentPage+2)
        {
            //keep it visible
            if (!itemView.isLoaded) {
                [itemView layoutWithData:[self.items objectAtIndex:itemView.tag-1]];
            }
        }
        else
        {
            //hide it
            if (itemView.isLoaded) {
                [itemView unloadData];
            }

        }
    }
}

如果视图距离屏幕显示 +/- 2 个“页面”,则基本上会加载该视图。这大大减少了我正在使用的内存量(而不是一次加载 20 多个 ItemView),这很好。但是,所有加载/卸载确实使滚动有点不稳定,尤其是在速度较慢的设备上。这是 ItemView 加载时实际发生的情况:

- (void)layoutWithData:(Item*)_data {
    self.data = _data;

//grab the image from the bundle
    UIImage *img;
    NSString *filePath = [[NSBundle mainBundle] pathForResource:_data.image ofType:@"jpg"];
        if(filePath.length > 0 && filePath != (id)[NSNull null]) {
            img = [UIImage imageWithContentsOfFile:filePath];
        }

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    [btn setImage:img forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(tapDetected:) forControlEvents:UIControlEventTouchUpInside];
    btn.frame = CGRectMake(0, 0, kItemPosterWidthIphone, kItemPosterHeightIphone);
    [self addSubview:btn];

    self.isLoaded = YES;

}

以及ItemView的卸载:

- (void)unloadData{
    for(UIView *subview in [self subviews]) {
        [subview removeFromSuperview];
    }
    self.data = nil;
    self.isLoaded = NO;
}

再次,我可以做些什么来加快加载/卸载速度,从而使 UIScrollView 更流畅?


尝试异步:

- (void)layoutWithData:(Item*)_data {
    self.data = _data;
    self.isLoaded = YES;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        UIImage *img;
        NSString *filePath = [[NSBundle mainBundle] pathForResource:_data.image ofType:@"jpg"];
            if(filePath.length > 0 && filePath != (id)[NSNull null]) {
                img = [UIImage imageWithContentsOfFile:filePath];
            }

        dispatch_async(dispatch_get_main_queue(), ^{
            UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
            [btn setImage:img forState:UIControlStateNormal];
            [btn addTarget:self action:@selector(tapDetected:) forControlEvents:UIControlEventTouchUpInside];
            btn.frame = CGRectMake(0, 0, kItemPosterWidthIphone, kItemPosterHeightIphone);
            self.imageView = btn;
            [self addSubview:btn];


        });

    });
}

【问题讨论】:

    标签: ios performance uiscrollview uiscrollviewdelegate


    【解决方案1】:

    不久前我遇到了这个问题,我将加载图像从磁盘移动到后台线程。试试看是否更快。

    请看这里:loading images from disk in iPhone app is slow

    编辑:图像加载滞后也可能是由于 UIImages 的延迟处理造成的

    请看这里:Setting image property of UIImageView causes major lag

    【讨论】:

    • 好建议。不幸的是,它在旧设备上仍然滞后。你能看看我在“尝试异步”下的编辑,看看我做错了什么吗?
    • 也许在速度较慢的设备上,将其绘制在屏幕上会使其滞后。我解决了在速度较慢的设备上使用缩略图(也就是质量较低的图像)的问题。您正在后台线程中正确加载图像。你的图像真的是高清的吗?他们需要那么高清吗?
    • 你好,请阅读这个问题:stackoverflow.com/questions/10790183/…这可能是你的问题
    • 谢谢,这看起来也很有希望。但我收到错误:: CGContextDrawImage: invalid context 0x0
    • 还有这个:CGBitmapContextCreateImage:无效的上下文 0x0
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-05
    相关资源
    最近更新 更多