apache / incubator-weex

Apache Weex (Incubating)
https://weex.apache.org
Apache License 2.0
13.75k stars 1.81k forks source link

[iOS] 修复使用 Xcode 12 构建且运行在 iOS 14 上时图片不加载的问题 #3268

Closed dorentus closed 4 years ago

dorentus commented 4 years ago

Brief Description of the PR

直接触发问题的地方大致是在这里

之前,设置 UIImageViewimage 属性之后,系统会直接更新 layer.contents ,但是在 Xcode 12 + iOS 14 之后,系统不会立即更新 layer.contents,而是会在合适的时机(可能是去调用 -display 方法)去更新视图。我们这里把 layerClass 改了,重写了 -display 且没有调用父类的实现,就造成在这种情况下永远不会更新视图了。

修复的方法可以是为 WXImageView 单独配置一个 WXLayer 的子类作为 layerClass,在这个子类的 -display 实现里面,针对 Xcode 12 + iOS 14 这种情况,手动调用 WXLayer 父类(也就是 CALayer)的 -display 方法。

但是仔细检查代码看来,这整个 WXImageView 及相关覆盖应该都是没有必要存在的,于是就有了这个直接改用 UIImageView 的补丁。


Demo link: http://dotwe.org/vue/4a42a418f7531d2ece3c52d2baf7291c

weex-bot commented 4 years ago
Warnings
:warning: No Changelog changes! - Can you add a Changelog? To do so,append your changes to the changelog.md
:warning: Current pr not bind the milestone
:warning: If your PR is about fixing a bug excluding crash the code,you should add the demo link in the PR description. Demo link: http://dotwe.org/vue

Generated by :no_entry_sign: dangerJS against ed364071c95fb00cc14c8100a32134708f0e51fc

KitsGithub commented 4 years ago

我看了一下WXComponent+Displayt.m感觉如果强行把WXImageView移除掉会影响自带的一些统计指标啊。 @dorentus

dorentus commented 3 years ago

我这边使用 https://github.com/apache/incubator-weex/pull/3276 之后还是会遇到图片不显示的问题,不是所有图片,随机有部分图片显示不出来,每次不同。调试显示对应的 WXImageViewimage 属性都有值,但是没有显示出来。

现在我用了这样的方式绕过:

diff --git a/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m
index 628033fbe541cf4b9506d4279ad99615e0d616fc..2f02c2580aafd66f81a2cf3001d1e09dc1fe0838 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m
@@ -35,6 +35,26 @@
 #import <pthread/pthread.h>
 #import "WXMonitor.h"
 #import "WXSDKInstance_performance.h"
+#import <objc/message.h>
+
+@interface WXImageLayer : WXLayer
+
+@end
+
+@implementation WXImageLayer
+
+- (void)display
+{
+    if (@available(iOS 14.0, *)) {
+        // call -[CALayer display]
+        struct objc_super s = {.receiver = self, .super_class = self.superclass.superclass};
+        ((void (*)(struct objc_super *, SEL))objc_msgSendSuper)(&s, _cmd);
+    }
+
+    [super display];
+}
+
+@end

 @interface WXImageView : UIImageView

@@ -44,7 +64,7 @@

 + (Class)layerClass
 {
-    return [WXLayer class];
+    return [WXImageLayer class];
 }

 @end