【问题标题】:iCarousel viewForItemAtIndex using custom UIView resuses first images loadediCarousel viewForItemAtIndex 使用自定义 UIView 重新使用加载的第一个图像
【发布时间】:2012-07-02 22:23:31
【问题描述】:

我在使用 iCarousel 和 UIImageViews 时没有问题,一切都很好。

但是,我想在图像中添加一些额外的绘图,所以我做了一个 UIView 的快速子类,其中包含一个图像并有一个自定义的绘图例程。很简单。但是,在 viewForItemAtIndex 内部,当我设置图像属性时,它不会在视觉上更新。相反,它会重复代表可见图像的 n 个图像,从而重复最初加载的对象。

例如,我有 26 张图片,a - z。 5 在启动时可见,a - e。如果没有“setNeedsReload”,当我滚动视图时,我会重复获取图像 a - e,而不是 a - z。

我发现,如果我在 setImage 属性中添加 'setNeedsDisplay',它将正常工作。但是,这会带来巨大的性能损失。

我的问题有两个:

  1. 我错过了什么吗?
  2. 我是否应该只扩展 UIImageView 并 在像 Nick 这样的 'processImage' 样式方法中进行自定义绘图 在 FXImage 中做过吗?

谢谢,

/// GroupImageView.m

- (void)setImage:(UIImage *)newImage {
    image = newImage;
    [self setNeedsDisplay];
}

// override of the drawRect routine.
- (void)drawRect:(CGRect)rect {

    //  only draw if we have an image to draw
    if (image) {
        CGContextRef context = UIGraphicsGetCurrentContext();

        // blah blah, fancy drawing crap
        CGContextRotateCTM (context, radians((rand() % 5 + 2)));
        CGContextTranslateCTM(context, -0.5f * insetRect.size.width, -0.5f * insetRect.size.height);
        CGContextFillRect(context,insetRect);
        // etc

        [image drawInRect:insetRect blendMode:kCGBlendModeNormal alpha:[self alpha]];

        // etc
    } 
}

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view {

    if (view == nil) {
        view = [[GroupImageView alloc] initWithImage:[UIImage imageNamed:@"Loading.png"]];
    }
    CGImageRef ref = [group posterImage];
    UIImage* coverImage;
    if (ref) {
        coverImage = [UIImage imageWithCGImage:ref scale:1/scaleFactor orientation:UIImageOrientationUp];
    }
    else {
        coverImage = [UIImage imageNamed:@"Sunflower.png"];
    }

    [(GroupImageView*)view setImage:coverImage];
    return view;

}

【问题讨论】:

    标签: ios uiview uiimageview icarousel


    【解决方案1】:

    UIImageView 不使用 drawRect 来绘制图像,因为 drawRect 使用 Core Graphics 进行绘制,而 Core Graphics 不是硬件加速的。

    使用 drawRect 绘制其内容的 UIView 子类将比 UIImageView 慢 100 倍,这就是您遇到性能问题的原因。

    FXImageView 通过在后台线程上进行绘图并使用 NSOperationQueue 来确保图像根据需要按顺序更新来解决这个问题。

    分叉 FXImageView 并修改 processImage 方法来进行绘图并不是一个坏主意 - 它肯定会比从头开始重新创建 FXImageView 的排队和缓存行为少。请注意,您还需要修改缓存键逻辑,因为 FXImageView 的缓存基于它使用的特定绘图属性。

    我可能会考虑更新 FXImageView 以包含自定义绘图块属性 - 这似乎很有用。

    【讨论】:

    • 谢谢尼克。我认为 UIImageView 正在进行一些优化。我仍然不明白为什么在轮播中重复使用旧图像,但我的 tableview 中没有类似的 UIView 子类的相同问题。仍然看起来很奇怪,但我可以忍受它。 (显然需要通过自定义处理将我的 UIViews 重构为 UIImageViews)我想我将分叉或扩展 FXImageView 以便我可以进行更优化的绘图。感谢您对缓存键逻辑的提醒,我会牢记这一点。
    • 如果有帮助,我很乐意为 FXImageView 清除自定义绘图块,您可以查看一下。
    • 我已将一个新版本上传到 github,其中包含自定义效果块属性
    • 哇,尼克,太棒了。我已经启动并运行它并且非常感谢它。性能要好得多... 一个小问题,由于遗留代码,我原来的视图是“initWithImage”。 FXImageView 实际上并没有覆盖它,因此没有调用“设置”并且没有任何作用。我花了几分钟才意识到其中的差异并加以追踪。
    • 哦,好点子。可能最好在 Github 上而不是在这里提交任何未来的问题;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多