Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ios 14 YYAnimatedImageView 加载不出图片 #242

Open
NicofnCHINA opened this issue Jul 1, 2020 · 17 comments
Open

ios 14 YYAnimatedImageView 加载不出图片 #242

NicofnCHINA opened this issue Jul 1, 2020 · 17 comments

Comments

@NicofnCHINA
Copy link

ios 14 YYAnimatedImageView 加载不出图片

@q819438477
Copy link

q819438477 commented Jul 3, 2020

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

@wongzigii
Copy link

@mlch911
Copy link

mlch911 commented Jul 21, 2020

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
Copy link

TzyTman commented Sep 24, 2020

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
Copy link

mlch911 commented Sep 24, 2020

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
Copy link

TzyTman commented Sep 24, 2020

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以下 就可以循环播放

@mlch911
Copy link

mlch911 commented Sep 24, 2020

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加载不出普通的图片,然后改了就可以加载出来了。
你这个问题,你再找找别的吧

@TzyTman
Copy link

TzyTman commented Sep 24, 2020 via email

@NicofnCHINA
Copy link
Author

NicofnCHINA commented Sep 25, 2020

写了个分类

.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

@JRJian
Copy link

JRJian commented Sep 25, 2020

@NicofnCHINA NICE完美解决方案~

@y500
Copy link

y500 commented Sep 29, 2020

写了个分类

.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

@aptx5788
Copy link

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

@tigerzhang08
Copy link

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

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

@jiabibi888
Copy link

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即可。

@cuilinhao
Copy link

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

没什么用啊?

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

@SunZhiC
Copy link

SunZhiC commented Apr 13, 2022

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
Copy link

SunZhiC commented Apr 13, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests