From 4ad278e9c9b71c8019c9fb2ce4e59b0c7fd5be20 Mon Sep 17 00:00:00 2001 From: pengfeizhou Date: Thu, 28 Jan 2021 20:55:03 +0800 Subject: [PATCH] iOS:Support SDWebImage --- doric-cli/target/iOS/Podfile | 2 +- doric-demo/src/ImageDemo.ts | 154 ------------------ .../Example/Example.xcodeproj/project.pbxproj | 60 +++---- doric-iOS/Example/Podfile | 6 +- doric-iOS/Pod/Classes/Shader/DoricImageNode.m | 61 ++++++- 5 files changed, 96 insertions(+), 187 deletions(-) diff --git a/doric-cli/target/iOS/Podfile b/doric-cli/target/iOS/Podfile index 446ca8b1..c72f0dc5 100644 --- a/doric-cli/target/iOS/Podfile +++ b/doric-cli/target/iOS/Podfile @@ -10,7 +10,7 @@ source 'https://cdn.cocoapods.org/' target '__$__' do # Comment the next line if you don't want to use dynamic frameworks - use_frameworks! + use_modular_headers! # Pods for __$__ pod 'DoricCore', "#{version}" diff --git a/doric-demo/src/ImageDemo.ts b/doric-demo/src/ImageDemo.ts index e41d4f15..0608babe 100644 --- a/doric-demo/src/ImageDemo.ts +++ b/doric-demo/src/ImageDemo.ts @@ -23,166 +23,12 @@ class ImageDemo extends Panel { textAlignment: gravity().center(), height: 50, }), - - label('Button'), - image({ - imageBase64: button, - scaleType: ScaleType.ScaleToFill, - layoutConfig: { - widthSpec: LayoutSpec.FIT, - heightSpec: LayoutSpec.FIT, - }, - imageScale: 2, - }), - image({ - imageBase64: button, - scaleType: ScaleType.ScaleToFill, - layoutConfig: { - widthSpec: LayoutSpec.FIT, - heightSpec: LayoutSpec.FIT, - }, - }), - image({ - imageBase64: button, - scaleType: ScaleType.ScaleToFill, - layoutConfig: { - widthSpec: LayoutSpec.JUST, - heightSpec: LayoutSpec.JUST, - }, - width: 200, - height: 150 / 2.75, - stretchInset: { - left: 100, - top: 0, - right: 100, - bottom: 0 - }, - imageScale: 2.75, - }), - image({ - imageBase64: button, - scaleType: ScaleType.ScaleToFill, - layoutConfig: { - widthSpec: LayoutSpec.JUST, - heightSpec: LayoutSpec.JUST, - }, - width: 200, - height: 75, - stretchInset: { - left: 100, - top: 0, - right: 100, - bottom: 0 - }, - imageScale: 2, - }), - label('Gif'), - image({ - imageUrl: "https://misc.aotu.io/ONE-SUNDAY/world-cup_2014_42.gif", - scaleType: ScaleType.ScaleToFill, - loadCallback: function (ret) { - log('this') - log('loadCallback', ret) - }, - imageScale: 2, - }), - label('APNG'), - image({ - imageUrl: "https://misc.aotu.io/ONE-SUNDAY/world_cup_2014_42.png", - loadCallback: (ret) => { - } - }), label('Animated WebP'), image({ imageUrl: "https://p.upyun.com/demo/webp/webp/animated-gif-0.webp", loadCallback: (ret) => { } }), - label('WebP'), - imageView = image({ - imageUrl: "https://p.upyun.com/demo/webp/webp/jpg-0.webp", - layoutConfig: layoutConfig().just(), - width: 200, - height: 200, - // loadCallback: (ret) => { - // if (ret) { - // imageView.width = ret.width - // imageView.height = ret.height - // } - // } - }), - label('ScaleToFill'), - image({ - imageUrl, - width: 300, - height: 300, - isBlur: true, - border: { - width: 2, - color: Color.GRAY, - }, - scaleType: ScaleType.ScaleToFill, - layoutConfig: layoutConfig().just(), - loadCallback: (ret) => { - } - }), - label('ScaleAspectFit'), - image({ - imageUrl, - width: 300, - height: 300, - border: { - width: 2, - color: Color.GRAY, - }, - scaleType: ScaleType.ScaleAspectFit, - layoutConfig: layoutConfig().just(), - }), - label('ScaleAspectFill'), - image({ - imageUrl, - width: 300, - height: 300, - border: { - width: 2, - color: Color.GRAY, - }, - scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().just(), - }), - label('ImageBase64'), - image({ - imageBase64: img_base64[0], - width: 300, - height: 300, - border: { - width: 2, - color: Color.GRAY, - }, - scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().just(), - }), - label('StretchInset'), - image({ - imageBase64: img_base64[1], - height: 60, - width: 134, - scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().just(), - }), - image({ - imageBase64: img_base64[1], - height: 60, - width: 294, - scaleType: ScaleType.ScaleToFill, - layoutConfig: layoutConfig().just(), - stretchInset: { - left: 0.85, - top: 0, - right: 0.149, - bottom: 0 - } - }), ], { layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), diff --git a/doric-iOS/Example/Example.xcodeproj/project.pbxproj b/doric-iOS/Example/Example.xcodeproj/project.pbxproj index 1d16852b..aa0537f8 100644 --- a/doric-iOS/Example/Example.xcodeproj/project.pbxproj +++ b/doric-iOS/Example/Example.xcodeproj/project.pbxproj @@ -7,8 +7,9 @@ objects = { /* Begin PBXBuildFile section */ - 2D1E3FCC945892E89F8CD721 /* Pods_ExampleUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A70E07B04DE158DDCE89CBB /* Pods_ExampleUITests.framework */; }; - 5D8F2ECF411563EE2D2C7644 /* Pods_ExampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A11C0EBA10EB490A8508592 /* Pods_ExampleTests.framework */; }; + 0D90124EDB10BB254CBAD76B /* libPods-ExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A68295410FE7498FAFBB726 /* libPods-ExampleTests.a */; }; + 1BCA4753C9D35032A0288028 /* libPods-ExampleUITests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD2D6CCC8DCDABA7F86EAE7C /* libPods-ExampleUITests.a */; }; + 52F56220E3A039DD5E3EA3B2 /* libPods-Example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4650C6577493F533466F084B /* libPods-Example.a */; }; 8B429D94241B66A300572570 /* iconfont.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8B429D93241B66A200572570 /* iconfont.ttf */; }; 8BCADA7C23CD5B65005EEF96 /* NavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BCADA7B23CD5B64005EEF96 /* NavigationController.m */; }; D751D4B065D8D4FA6594B5EE /* DemoVC.m in Sources */ = {isa = PBXBuildFile; fileRef = D751D19E97EF4EDD7588FEBE /* DemoVC.m */; }; @@ -22,7 +23,6 @@ E2334B0822E9D2070098A085 /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334B0722E9D2070098A085 /* ExampleTests.m */; }; E2334B1322E9D2070098A085 /* ExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2334B1222E9D2070098A085 /* ExampleUITests.m */; }; E2C9315923B0A263007933D9 /* src in Resources */ = {isa = PBXBuildFile; fileRef = E2C9315823B0A263007933D9 /* src */; }; - FD27ECDD5DF3C29A006388FB /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AD9E80F80285B084B563B4D /* Pods_Example.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -44,11 +44,10 @@ /* Begin PBXFileReference section */ 016E930415B91D826F9FFF47 /* Pods-ExampleUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleUITests/Pods-ExampleUITests.debug.xcconfig"; sourceTree = ""; }; - 0A11C0EBA10EB490A8508592 /* Pods_ExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 0AD9E80F80285B084B563B4D /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3D75F592D76A665674B31A66 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; }; - 6A70E07B04DE158DDCE89CBB /* Pods_ExampleUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExampleUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4650C6577493F533466F084B /* libPods-Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Example.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 8231E841CCAF382F85C9F576 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = ""; }; + 8A68295410FE7498FAFBB726 /* libPods-ExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 8B429D93241B66A200572570 /* iconfont.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = iconfont.ttf; path = "../../../doric-demo/bundle/iconfont.ttf"; sourceTree = ""; }; 8BCADA7A23CD5B5F005EEF96 /* NavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NavigationController.h; sourceTree = ""; }; 8BCADA7B23CD5B64005EEF96 /* NavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavigationController.m; sourceTree = ""; }; @@ -76,6 +75,7 @@ E2334B1222E9D2070098A085 /* ExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleUITests.m; sourceTree = ""; }; E2334B1422E9D2070098A085 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; E2C9315823B0A263007933D9 /* src */ = {isa = PBXFileReference; lastKnownFileType = folder; name = src; path = "../../../doric-demo/bundle/src"; sourceTree = ""; }; + FD2D6CCC8DCDABA7F86EAE7C /* libPods-ExampleUITests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExampleUITests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -83,7 +83,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FD27ECDD5DF3C29A006388FB /* Pods_Example.framework in Frameworks */, + 52F56220E3A039DD5E3EA3B2 /* libPods-Example.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -91,7 +91,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5D8F2ECF411563EE2D2C7644 /* Pods_ExampleTests.framework in Frameworks */, + 0D90124EDB10BB254CBAD76B /* libPods-ExampleTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -99,7 +99,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2D1E3FCC945892E89F8CD721 /* Pods_ExampleUITests.framework in Frameworks */, + 1BCA4753C9D35032A0288028 /* libPods-ExampleUITests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -122,9 +122,9 @@ D80A9B07B39AD04027CAE17B /* Frameworks */ = { isa = PBXGroup; children = ( - 0AD9E80F80285B084B563B4D /* Pods_Example.framework */, - 0A11C0EBA10EB490A8508592 /* Pods_ExampleTests.framework */, - 6A70E07B04DE158DDCE89CBB /* Pods_ExampleUITests.framework */, + 4650C6577493F533466F084B /* libPods-Example.a */, + 8A68295410FE7498FAFBB726 /* libPods-ExampleTests.a */, + FD2D6CCC8DCDABA7F86EAE7C /* libPods-ExampleUITests.a */, ); name = Frameworks; sourceTree = ""; @@ -205,7 +205,7 @@ E2334AE722E9D2060098A085 /* Sources */, E2334AE822E9D2060098A085 /* Frameworks */, E2334AE922E9D2060098A085 /* Resources */, - CAB216147AA83A39AD1C627A /* [CP] Embed Pods Frameworks */, + 405670BCF5DC51D2DB74427C /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -349,6 +349,23 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 405670BCF5DC51D2DB74427C /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 48D050F720D3A879060292A8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -393,23 +410,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - CAB216147AA83A39AD1C627A /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; E24A030C22EED0D500AB4631 /* Package JS Bundle */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/doric-iOS/Example/Podfile b/doric-iOS/Example/Podfile index 4708a764..1c37501b 100644 --- a/doric-iOS/Example/Podfile +++ b/doric-iOS/Example/Podfile @@ -3,7 +3,7 @@ target 'Example' do - use_frameworks! + use_modular_headers! pod 'DoricCore', :path => '../../' pod 'DoricDevkit', :path => '../../' @@ -12,6 +12,10 @@ target 'Example' do #pod 'YYImage/WebP' + pod 'SDWebImage' + + pod 'SDWebImageWebPCoder' + target 'ExampleTests' do inherit! :search_paths # Pods for testing diff --git a/doric-iOS/Pod/Classes/Shader/DoricImageNode.m b/doric-iOS/Pod/Classes/Shader/DoricImageNode.m index f9cbdf39..61fb457c 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricImageNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricImageNode.m @@ -23,6 +23,7 @@ #import "DoricImageNode.h" #import "DoricExtensions.h" #import "DoricUtil.h" +#import "DoricSuperNode.h" #if __has_include() @@ -44,8 +45,18 @@ - (void)displayLayer:(CALayer *)layer { } } @end -#else +#elif __has_include() + +#import + +@interface DoricImageView : SDAnimatedImageView +@end + +@implementation DoricImageView +@end + +#else @interface DoricImageView : UIImageView @end @@ -118,6 +129,8 @@ - (UIImage *)currentPlaceHolderImage { options:NSDataBase64DecodingIgnoreUnknownCharacters]; #if __has_include() YYImage *image = [YYImage imageWithData:imageData scale:self.imageScale]; +#elif __has_include() + SDAnimatedImage *image = [SDAnimatedImage imageWithData:imageData scale:self.imageScale]; #else UIImage *image = [UIImage imageWithData:imageData scale:self.imageScale]; #endif @@ -155,6 +168,8 @@ - (UIImage *)currentErrorImage { options:NSDataBase64DecodingIgnoreUnknownCharacters]; #if __has_include() YYImage *image = [YYImage imageWithData:imageData scale:self.imageScale]; +#elif __has_include() + SDAnimatedImage *image = [SDAnimatedImage imageWithData:imageData scale:self.imageScale]; #else UIImage *image = [UIImage imageWithData:imageData scale:self.imageScale]; #endif @@ -216,6 +231,44 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id } } }]; +#elif __has_include() + [view sd_setImageWithURL:[NSURL URLWithString:prop] placeholderImage:[self currentPlaceHolderImage] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + __strong typeof(_self) self = _self; + if (self.placeHolderColor || self.errorColor) { + self.view.contentMode = self.contentMode; + } + view.doricLayout.undefined = NO; + if (error) { + [[self currentErrorImage] also:^(UIImage *it) { + self.view.image = it; + }]; + if (self.loadCallbackId.length > 0) { + [self callJSResponse:self.loadCallbackId, nil]; + } + } else { + if (image.scale != self.imageScale) { + if ([image isKindOfClass:SDAnimatedImage.class]) { + image = [SDAnimatedImage imageWithData:((SDAnimatedImage *) image).animatedImageData scale:self.imageScale]; + } else { + image = [UIImage imageWithCGImage:image.CGImage scale:self.imageScale orientation:image.imageOrientation]; + } + self.view.image = image; + } + if (self.loadCallbackId.length > 0) { + [self callJSResponse:self.loadCallbackId, + @{@"width": @(image.size.width), @"height": @(image.size.height)}, + nil]; + } + if (async) { + DoricSuperNode *node = self.superNode; + while (node.superNode != nil) { + node = node.superNode; + } + [node requestLayout]; + } + } + + }]; #else DoricLog(@"Do not support load image url"); #endif @@ -247,6 +300,8 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id options:NSDataBase64DecodingIgnoreUnknownCharacters]; #if __has_include() YYImage *image = [YYImage imageWithData:imageData scale:self.imageScale]; +#elif __has_include() + SDAnimatedImage *image = [SDAnimatedImage imageWithData:imageData scale:self.imageScale]; #else UIImage *image = [UIImage imageWithData:imageData scale:self.imageScale]; #endif @@ -284,6 +339,8 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id } else if ([@"imageRes" isEqualToString:name]) { #if __has_include() YYImage *image = [YYImage imageNamed:prop]; +#elif __has_include() + SDAnimatedImage *image = [SDAnimatedImage imageNamed:prop]; #else UIImage *image = [UIImage imageNamed:prop]; #endif @@ -309,6 +366,8 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id NSData *imgData = [[NSData alloc] initWithContentsOfFile:fullPath]; #if __has_include() YYImage *image = [YYImage imageWithData:imgData scale:self.imageScale]; +#elif __has_include() + SDAnimatedImage *image = [SDAnimatedImage imageWithData:imgData scale:self.imageScale]; #else UIImage *image = [UIImage imageWithData:imgData scale:self.imageScale]; #endif