YYWebImage icon indicating copy to clipboard operation
YYWebImage copied to clipboard

ios 14 YYAnimatedImageView 加载不出图片

Open NicofnCHINA opened this issue 5 years ago • 17 comments

ios 14 YYAnimatedImageView 加载不出图片

NicofnCHINA avatar Jul 01 '20 02:07 NicofnCHINA

ios 14 YYAnimatedImageView 加载不出图片。用Xcode-beta 12.0版的。

q819438477 avatar Jul 03 '20 09:07 q819438477

https://github.com/SDWebImage/SDWebImage/issues/3040

wongzigii avatar Jul 07 '20 06:07 wongzigii

ios14里重写了displayLayer:方法会有问题,看了下,应该是这样改。最下边注释的是原来的,不知道正式版的苹果会不会修复这个问题。

- (void)displayLayer:(CALayer *)layer {
    UIImage *currentFrame = _curFrame;
    if (currentFrame) {
        layer.contentsScale = currentFrame.scale;
        layer.contents = (__bridge id)currentFrame.CGImage;
    } else {
        // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering.
        if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) {
           [super displayLayer:layer];
        }
    }
//    if (_curFrame) {
//        layer.contents = (__bridge id)_curFrame.CGImage;
//    }
}

mlch911 avatar Jul 21 '20 02:07 mlch911

ios14里重写了displayLayer:方法会有问题,看了下,应该是这样改。最下边注释的是原来的,不知道正式版的苹果会不会修复这个问题。

- (void)displayLayer:(CALayer *)layer {
    UIImage *currentFrame = _curFrame;
    if (currentFrame) {
        layer.contentsScale = currentFrame.scale;
        layer.contents = (__bridge id)currentFrame.CGImage;
    } else {
        // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering.
        if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) {
           [super displayLayer:layer];
        }
    }
//    if (_curFrame) {
//        layer.contents = (__bridge id)_curFrame.CGImage;
//    }
}

没什么用啊?

TzyTman avatar Sep 24 '20 02:09 TzyTman

ios14里重写了displayLayer:方法会有问题,看了下,应该是这样改。最下边注释的是原来的,不知道正式版的苹果会不会修复这个问题。

- (void)displayLayer:(CALayer *)layer {
    UIImage *currentFrame = _curFrame;
    if (currentFrame) {
        layer.contentsScale = currentFrame.scale;
        layer.contents = (__bridge id)currentFrame.CGImage;
    } else {
        // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering.
        if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) {
           [super displayLayer:layer];
        }
    }
//    if (_curFrame) {
//        layer.contents = (__bridge id)_curFrame.CGImage;
//    }
}

没什么用啊?

我这儿是没问题的啊,改了就好了

mlch911 avatar Sep 24 '20 02:09 mlch911

ios14里重写了displayLayer:方法会有问题,看了下,应该是这样改。最下边注释的是原来的,不知道正式版的苹果会不会修复这个问题。

- (void)displayLayer:(CALayer *)layer {
    UIImage *currentFrame = _curFrame;
    if (currentFrame) {
        layer.contentsScale = currentFrame.scale;
        layer.contents = (__bridge id)currentFrame.CGImage;
    } else {
        // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering.
        if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) {
           [super displayLayer:layer];
        }
    }
//    if (_curFrame) {
//        layer.contents = (__bridge id)_curFrame.CGImage;
//    }
}

没什么用啊?

我这儿是没问题的啊,改了就好了

YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:[YYImage imageNamed:@"voice"]];
imageView.frame = CGRectMake(100, 100, 50, 50);
[self.view addSubview:imageView];

这里的Voice 是Gif 图片 只播放一下 就暂停了 但是在IOS14以下 就可以循环播放

TzyTman avatar Sep 24 '20 02:09 TzyTman

ios14里重写了displayLayer:方法会有问题,看了下,应该是这样改。最下边注释的是原来的,不知道正式版的苹果会不会修复这个问题。

- (void)displayLayer:(CALayer *)layer {
    UIImage *currentFrame = _curFrame;
    if (currentFrame) {
        layer.contentsScale = currentFrame.scale;
        layer.contents = (__bridge id)currentFrame.CGImage;
    } else {
        // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering.
        if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) {
           [super displayLayer:layer];
        }
    }
//    if (_curFrame) {
//        layer.contents = (__bridge id)_curFrame.CGImage;
//    }
}

没什么用啊?

我这儿是没问题的啊,改了就好了

YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:[YYImage imageNamed:@"voice"]];
imageView.frame = CGRectMake(100, 100, 50, 50);
[self.view addSubview:imageView];

这里的Voice 是Gif 图片 只播放一下 就暂停了 但是在IOS14以下 就可以循环播放

这和我说的不是一个问题啊……我说的是ios14beta上,YYImageView加载不出普通的图片,然后改了就可以加载出来了。 你这个问题,你再找找别的吧

mlch911 avatar Sep 24 '20 02:09 mlch911

好吧

------------------ 原始邮件 ------------------ 发件人: "mlch911"<[email protected]>; 发送时间: 2020年9月24日(星期四) 上午10:35 收件人: "ibireme/YYWebImage"<[email protected]>; 抄送: "若干年后"<[email protected]>; "Comment"<[email protected]>; 主题: Re: [ibireme/YYWebImage] ios 14 YYAnimatedImageView 加载不出图片 (#242)

ios14里重写了displayLayer:方法会有问题,看了下,应该是这样改。最下边注释的是原来的,不知道正式版的苹果会不会修复这个问题。

  • (void)displayLayer:(CALayer *)layer { UIImage *currentFrame = _curFrame; if (currentFrame) { layer.contentsScale = currentFrame.scale; layer.contents = (__bridge id)currentFrame.CGImage; } else { // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering. if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) { [super displayLayer:layer]; } } // if (_curFrame) { // layer.contents = (__bridge id)_curFrame.CGImage; // } }

没什么用啊?

我这儿是没问题的啊,改了就好了 YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:[YYImage imageNamed:@"voice"]]; imageView.frame = CGRectMake(100, 100, 50, 50); [self.view addSubview:imageView];
这里的Voice 是Gif 图片 只播放一下 就暂停了 但是在IOS14以下 就可以循环播放

这和我说的不是一个问题啊……我说的是ios14beta上,YYImageView加载不出普通的图片,然后改了就可以加载出来了。 你这个问题,你再找找别的吧

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

TzyTman avatar Sep 24 '20 02:09 TzyTman

写了个分类

.h

//
//  YYAnimatedImageView+OLELayer.h
//  OLA-iOS
//
//  Created by niuge on 2020/9/25.
//  Copyright © 2020 olecx. All rights reserved.
//

#import <YYImage/YYImage.h>

NS_ASSUME_NONNULL_BEGIN

@interface YYAnimatedImageView (OLELayer)

@end

NS_ASSUME_NONNULL_END

.m

//
//  YYAnimatedImageView+OLELayer.m
//  OLA-iOS
//
//  Created by niuge on 2020/9/25.
//  Copyright © 2020 olecx. All rights reserved.
//

#import "YYAnimatedImageView+OLELayer.h"

@implementation YYAnimatedImageView (OLELayer)

+ (void)load {
    
    Method displayLayerMethod = class_getInstanceMethod(self, @selector(displayLayer:));
   
    Method displayLayerNewMethod = class_getInstanceMethod(self, @selector(displayLayerNew:));
 
    method_exchangeImplementations(displayLayerMethod, displayLayerNewMethod);
}

- (void)displayLayerNew:(CALayer *)layer {
    
    Ivar imgIvar = class_getInstanceVariable([self class], "_curFrame");
    UIImage *img = object_getIvar(self, imgIvar);
    if (img) {
        layer.contents = (__bridge id)img.CGImage;
    } else {
        if (@available(iOS 14.0, *)) {
            [super displayLayer:layer];
        }
    }
}

@end

NicofnCHINA avatar Sep 25 '20 05:09 NicofnCHINA

@NicofnCHINA NICE完美解决方案~

JRJian avatar Sep 25 '20 10:09 JRJian

写了个分类

.h

//
//  YYAnimatedImageView+OLELayer.h
//  OLA-iOS
//
//  Created by niuge on 2020/9/25.
//  Copyright © 2020 olecx. All rights reserved.
//

#import <YYImage/YYImage.h>

NS_ASSUME_NONNULL_BEGIN

@interface YYAnimatedImageView (OLELayer)

@end

NS_ASSUME_NONNULL_END

.m

//
//  YYAnimatedImageView+OLELayer.m
//  OLA-iOS
//
//  Created by niuge on 2020/9/25.
//  Copyright © 2020 olecx. All rights reserved.
//

#import "YYAnimatedImageView+OLELayer.h"

@implementation YYAnimatedImageView (OLELayer)

+ (void)load {
    
    Method displayLayerMethod = class_getInstanceMethod(self, @selector(displayLayer:));
   
    Method displayLayerNewMethod = class_getInstanceMethod(self, @selector(displayLayerNew:));
 
    method_exchangeImplementations(displayLayerMethod, displayLayerNewMethod);
}

- (void)displayLayerNew:(CALayer *)layer {
    
    Ivar imgIvar = class_getInstanceVariable([self class], "_curFrame");
    UIImage *img = object_getIvar(self, imgIvar);
    if (img) {
        layer.contents = (__bridge id)img.CGImage;
    } else {
        if (@available(iOS 14.0, *)) {
            [super displayLayer:layer];
        }
    }
}

@end

good job

y500 avatar Sep 29 '20 09:09 y500

ios14 有两个问题: 1 gif 只播放一遍 无法重复播放 2 无法加载静态图 (用那个分类解决)

aptx5788 avatar Oct 22 '20 04:10 aptx5788

ios14 有两个问题: 1 gif 只播放一遍 无法重复播放 2 无法加载静态图 (用那个分类解决)

播放一遍的问题,可以看下 loopcount 的值

tigerzhang08 avatar Nov 24 '20 08:11 tigerzhang08

ios14里重写了displayLayer:方法会有问题,看了下,应该是这样改。最下边注释的是原来的,不知道正式版的苹果会不会修复这个问题。

- (void)displayLayer:(CALayer *)layer {
    UIImage *currentFrame = _curFrame;
    if (currentFrame) {
        layer.contentsScale = currentFrame.scale;
        layer.contents = (__bridge id)currentFrame.CGImage;
    } else {
        // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering.
        if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) {
           [super displayLayer:layer];
        }
    }
//    if (_curFrame) {
//        layer.contents = (__bridge id)_curFrame.CGImage;
//    }
}

没什么用啊?

我这儿是没问题的啊,改了就好了

YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:[YYImage imageNamed:@"voice"]];
imageView.frame = CGRectMake(100, 100, 50, 50);
[self.view addSubview:imageView];

这里的Voice 是Gif 图片 只播放一下 就暂停了 但是在IOS14以下 就可以循环播放

Gif图循环次数为1,在iOS14系统上就只播放一次,让UI重新生成一下gif即可。

jiabibi888 avatar Dec 18 '20 07:12 jiabibi888

ios14里重写了displayLayer:方法会有问题,看了下,应该是这样改。最下边注释的是原来的,不知道正式版的苹果会不会修复这个问题。

- (void)displayLayer:(CALayer *)layer {
    UIImage *currentFrame = _curFrame;
    if (currentFrame) {
        layer.contentsScale = currentFrame.scale;
        layer.contents = (__bridge id)currentFrame.CGImage;
    } else {
        // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering.
        if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) {
           [super displayLayer:layer];
        }
    }
//    if (_curFrame) {
//        layer.contents = (__bridge id)_curFrame.CGImage;
//    }
}

没什么用啊?

我测试了下,没问题,大佬

cuilinhao avatar Dec 29 '20 03:12 cuilinhao

ios14里重写了displayLayer:方法会有问题,看了下,应该是这样改。最下边注释的是原来的,不知道正式版的苹果会不会修复这个问题。

- (void)displayLayer:(CALayer *)layer {
    UIImage *currentFrame = _curFrame;
    if (currentFrame) {
        layer.contentsScale = currentFrame.scale;
        layer.contents = (__bridge id)currentFrame.CGImage;
    } else {
        // If we have no animation frames, call super implementation. iOS 14+ UIImageView use this delegate method for rendering.
        if ([UIImageView instancesRespondToSelector:@selector(displayLayer:)]) {
           [super displayLayer:layer];
        }
    }
//    if (_curFrame) {
//        layer.contents = (__bridge id)_curFrame.CGImage;
//    }
}

works well in iOS 15.3, great!

SunZhiC avatar Apr 13 '22 09:04 SunZhiC

import YYImage

extension YYAnimatedImageView {
    override open func display(_ layer: CALayer) {
        let currentFrame = value(forKeyPath: "_curFrame") as? UIImage
        
        if currentFrame != nil {
            layer.contentsScale = currentFrame!.scale
            layer.contents = currentFrame!.cgImage
        } else {
            if UIImageView.instancesRespond(to: #selector(display(_:))) {
                super.display(layer)
            }
        }
    }
}

This is a swift 5.5 version extension, will fix this bug.

SunZhiC avatar Apr 13 '22 09:04 SunZhiC