From ab11ee3372d01688e08f176c2e90465da8d290d6 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Thu, 9 Apr 2020 13:30:31 +0800 Subject: [PATCH] iOS:use image to implement gradient background color --- doric-iOS/Pod/Classes/Shader/DoricGroupNode.m | 1 + doric-iOS/Pod/Classes/Shader/DoricImageNode.m | 2 +- .../Classes/Shader/DoricNestedSliderNode.m | 1 + doric-iOS/Pod/Classes/Shader/DoricViewNode.m | 114 ++++++++++-------- 4 files changed, 70 insertions(+), 48 deletions(-) diff --git a/doric-iOS/Pod/Classes/Shader/DoricGroupNode.m b/doric-iOS/Pod/Classes/Shader/DoricGroupNode.m index a7389b1e4..ae38a5c3e 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricGroupNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricGroupNode.m @@ -157,6 +157,7 @@ - (DoricViewNode *)subNodeWithViewId:(NSString *)viewId { } - (void)requestLayout { + [super requestLayout]; for (DoricViewNode *node in self.childNodes) { [node requestLayout]; } diff --git a/doric-iOS/Pod/Classes/Shader/DoricImageNode.m b/doric-iOS/Pod/Classes/Shader/DoricImageNode.m index da73cf72e..21a9648b5 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricImageNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricImageNode.m @@ -112,7 +112,7 @@ - (UIImage *)currentErrorImage { - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id)prop { if ([@"imageUrl" isEqualToString:name]) { __weak typeof(self) _self = self; - BOOL async = NO; + __block BOOL async = NO; [view yy_setImageWithURL:[NSURL URLWithString:prop] placeholder:[self currentPlaceHolderImage] options:0 completion:^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) { __strong typeof(_self) self = _self; if (self.placeHolderColor || self.errorColor) { diff --git a/doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.m b/doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.m index d1e41ffed..547b8a69d 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricNestedSliderNode.m @@ -66,6 +66,7 @@ - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { - (void)requestLayout { [self.childNodes forEachIndexed:^(DoricViewNode *node, NSUInteger idx) { + [node requestLayout]; [node.view.doricLayout apply:self.view.frame.size]; node.view.left = idx * self.view.width; }]; diff --git a/doric-iOS/Pod/Classes/Shader/DoricViewNode.m b/doric-iOS/Pod/Classes/Shader/DoricViewNode.m index a4e3915d6..d715412ac 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricViewNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricViewNode.m @@ -104,8 +104,8 @@ @interface DoricViewNode () @property(nonatomic, copy) NSNumber *rotation; @property(nonatomic, copy) NSNumber *pivotX; @property(nonatomic, copy) NSNumber *pivotY; - -@property(nonatomic, strong) CAGradientLayer *gradientLayer; +@property(nonatomic, strong) NSDictionary *gradientProps; +@property(nonatomic, assign) CGSize gradientSize; @end @implementation DoricViewNode @@ -139,11 +139,6 @@ - (void)blend:(NSDictionary *)props { } [self afterBlended:props]; [self transformProperties]; - [self.gradientLayer also:^(CAGradientLayer *it) { - dispatch_async(dispatch_get_main_queue(), ^{ - it.frame = CGRectMake(0, 0, self.view.width, self.view.height); - }); - }]; } - (void)afterBlended:(NSDictionary *)props { @@ -180,42 +175,7 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop if ([prop isKindOfClass:[NSNumber class]]) { view.backgroundColor = DoricColor(prop); } else if ([prop isKindOfClass:[NSDictionary class]]) { - if (_gradientLayer == nil) { - _gradientLayer = [[CAGradientLayer alloc] init]; - [view.layer addSublayer:self.gradientLayer]; - } - - NSDictionary *dict = prop; - UIColor *start = DoricColor(dict[@"start"]); - UIColor *end = DoricColor(dict[@"end"]); - int orientation = [dict[@"orientation"] intValue]; - - if (orientation == 0) { - self.gradientLayer.startPoint = CGPointMake(0, 0); - self.gradientLayer.endPoint = CGPointMake(0, 1); - } else if (orientation == 1) { - self.gradientLayer.startPoint = CGPointMake(1, 0); - self.gradientLayer.endPoint = CGPointMake(0, 1); - } else if (orientation == 2) { - self.gradientLayer.startPoint = CGPointMake(1, 0); - self.gradientLayer.endPoint = CGPointMake(0, 0); - } else if (orientation == 3) { - self.gradientLayer.startPoint = CGPointMake(1, 1); - self.gradientLayer.endPoint = CGPointMake(0, 0); - } else if (orientation == 4) { - self.gradientLayer.startPoint = CGPointMake(0, 1); - self.gradientLayer.endPoint = CGPointMake(0, 0); - } else if (orientation == 5) { - self.gradientLayer.startPoint = CGPointMake(0, 1); - self.gradientLayer.endPoint = CGPointMake(1, 0); - } else if (orientation == 6) { - self.gradientLayer.startPoint = CGPointMake(0, 0); - self.gradientLayer.endPoint = CGPointMake(1, 0); - } else if (orientation == 7) { - self.gradientLayer.startPoint = CGPointMake(0, 0); - self.gradientLayer.endPoint = CGPointMake(1, 1); - } - self.gradientLayer.colors = @[(__bridge id) start.CGColor, (__bridge id) end.CGColor]; + self.gradientProps = prop; } } else if ([name isEqualToString:@"alpha"]) { view.alpha = [prop floatValue]; @@ -347,7 +307,67 @@ + (__kindof DoricViewNode *)create:(DoricContext *)context withType:(NSString *) return viewNode; } +- (UIImage *)gradientImageFromColors:(NSArray *)colors + startPoint:(CGPoint)startPoint + endPoint:(CGPoint)endPoint + imgSize:(CGSize)imgSize { + UIGraphicsBeginImageContextWithOptions(imgSize, NO, [UIScreen mainScreen].scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSaveGState(context); + CGColorSpaceRef colorSpace = CGColorGetColorSpace((__bridge CGColorRef) colors.lastObject); + CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, NULL); + CGPoint start = (CGPoint) {startPoint.x * imgSize.width, startPoint.y * imgSize.height}; + CGPoint end = (CGPoint) {endPoint.x * imgSize.width, endPoint.y * imgSize.height}; + CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + CGGradientRelease(gradient); + CGContextRestoreGState(context); + UIGraphicsEndImageContext(); + return image; +} + - (void)requestLayout { + [self.gradientProps also:^(NSDictionary *dict) { + if (CGSizeEqualToSize(self.gradientSize, self.view.frame.size)) { + return; + } + self.gradientSize = self.view.frame.size; + UIColor *start = DoricColor(dict[@"start"]); + UIColor *end = DoricColor(dict[@"end"]); + int orientation = [dict[@"orientation"] intValue]; + CGPoint startPoint; + CGPoint endPoint; + if (orientation == 1) { + startPoint = CGPointMake(1, 0); + endPoint = CGPointMake(0, 1); + } else if (orientation == 2) { + startPoint = CGPointMake(1, 0); + endPoint = CGPointMake(0, 0); + } else if (orientation == 3) { + startPoint = CGPointMake(1, 1); + endPoint = CGPointMake(0, 0); + } else if (orientation == 4) { + startPoint = CGPointMake(0, 1); + endPoint = CGPointMake(0, 0); + } else if (orientation == 5) { + startPoint = CGPointMake(0, 1); + endPoint = CGPointMake(1, 0); + } else if (orientation == 6) { + startPoint = CGPointMake(0, 0); + endPoint = CGPointMake(1, 0); + } else if (orientation == 7) { + startPoint = CGPointMake(0, 0); + endPoint = CGPointMake(1, 1); + } else { + startPoint = CGPointMake(0, 0); + endPoint = CGPointMake(0, 1); + } + UIImage *gradientImage = [self gradientImageFromColors:@[(__bridge id) start.CGColor, (__bridge id) end.CGColor] + startPoint:startPoint + endPoint:endPoint + imgSize:self.gradientSize]; + self.view.backgroundColor = [UIColor colorWithPatternImage:gradientImage]; + }]; } - (NSNumber *)getWidth { @@ -381,16 +401,16 @@ - (void)blendLayoutConfig:(NSDictionary *)params { self.view.doricLayout.heightSpec = (DoricLayoutSpec) [it integerValue]; }]; [params[@"margin"] also:^(NSDictionary *it) { - [it[@"left"] also:^(NSNumber* it) { + [it[@"left"] also:^(NSNumber *it) { self.view.doricLayout.marginLeft = [it floatValue]; }]; - [it[@"top"] also:^(NSNumber* it) { + [it[@"top"] also:^(NSNumber *it) { self.view.doricLayout.marginTop = [it floatValue]; }]; - [it[@"right"] also:^(NSNumber* it) { + [it[@"right"] also:^(NSNumber *it) { self.view.doricLayout.marginRight = [it floatValue]; }]; - [it[@"bottom"] also:^(NSNumber* it) { + [it[@"bottom"] also:^(NSNumber *it) { self.view.doricLayout.marginBottom = [it floatValue]; }]; }];