You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by so...@apache.org on 2017/02/28 02:30:05 UTC
[25/50] incubator-weex git commit: + [ios] feature : add box-shadow
for iOS
+ [ios] feature : add box-shadow for iOS
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/64013ea4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/64013ea4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/64013ea4
Branch: refs/heads/0.11-dev
Commit: 64013ea4b9cf61b1cd017c18473dc80007fe66d9
Parents: 7ed89f9
Author: \u9f50\u5c71 <su...@163.com>
Authored: Wed Feb 22 23:05:14 2017 +0800
Committer: \u9f50\u5c71 <su...@163.com>
Committed: Wed Feb 22 23:05:14 2017 +0800
----------------------------------------------------------------------
ios/sdk/WeexSDK.xcodeproj/project.pbxproj | 16 ++++
ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.h | 19 +++++
ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.m | 92 +++++++++++++++++++++
ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.h | 7 +-
ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.m | 89 +++++++++++++++-----
5 files changed, 199 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/64013ea4/ios/sdk/WeexSDK.xcodeproj/project.pbxproj
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK.xcodeproj/project.pbxproj b/ios/sdk/WeexSDK.xcodeproj/project.pbxproj
index 6330741..86687e6 100644
--- a/ios/sdk/WeexSDK.xcodeproj/project.pbxproj
+++ b/ios/sdk/WeexSDK.xcodeproj/project.pbxproj
@@ -223,6 +223,10 @@
C4B834281DE69B09007AD27E /* WXPickerModule.h in Headers */ = {isa = PBXBuildFile; fileRef = C4B834261DE69B09007AD27E /* WXPickerModule.h */; };
C4C30DE81E1B833D00786B6C /* WXComponent+PseudoClassManagement.m in Sources */ = {isa = PBXBuildFile; fileRef = C4C30DE61E1B833D00786B6C /* WXComponent+PseudoClassManagement.m */; };
C4C30DE91E1B833D00786B6C /* WXComponent+PseudoClassManagement.h in Headers */ = {isa = PBXBuildFile; fileRef = C4C30DE71E1B833D00786B6C /* WXComponent+PseudoClassManagement.h */; };
+ C4D872211E5DDEDA00E39BC1 /* WXInnerLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D8721F1E5DDEDA00E39BC1 /* WXInnerLayer.m */; };
+ C4D872221E5DDEDA00E39BC1 /* WXInnerLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = C4D872201E5DDEDA00E39BC1 /* WXInnerLayer.h */; };
+ C4D872251E5DDF7500E39BC1 /* WXBoxShadow.h in Headers */ = {isa = PBXBuildFile; fileRef = C4D872231E5DDF7500E39BC1 /* WXBoxShadow.h */; };
+ C4D872261E5DDF7500E39BC1 /* WXBoxShadow.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D872241E5DDF7500E39BC1 /* WXBoxShadow.m */; };
C4F012791E1502A6003378D0 /* SRWebSocket+Weex.h in Headers */ = {isa = PBXBuildFile; fileRef = C4F012721E1502A6003378D0 /* SRWebSocket+Weex.h */; };
C4F0127A1E1502A6003378D0 /* SRWebSocket+Weex.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F012731E1502A6003378D0 /* SRWebSocket+Weex.m */; };
C4F0127B1E1502A6003378D0 /* WXWebSocketDefaultImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = C4F012741E1502A6003378D0 /* WXWebSocketDefaultImpl.h */; };
@@ -512,6 +516,10 @@
C4B834261DE69B09007AD27E /* WXPickerModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXPickerModule.h; sourceTree = "<group>"; };
C4C30DE61E1B833D00786B6C /* WXComponent+PseudoClassManagement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "WXComponent+PseudoClassManagement.m"; sourceTree = "<group>"; };
C4C30DE71E1B833D00786B6C /* WXComponent+PseudoClassManagement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WXComponent+PseudoClassManagement.h"; sourceTree = "<group>"; };
+ C4D8721F1E5DDEDA00E39BC1 /* WXInnerLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXInnerLayer.m; sourceTree = "<group>"; };
+ C4D872201E5DDEDA00E39BC1 /* WXInnerLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXInnerLayer.h; sourceTree = "<group>"; };
+ C4D872231E5DDF7500E39BC1 /* WXBoxShadow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXBoxShadow.h; sourceTree = "<group>"; };
+ C4D872241E5DDF7500E39BC1 /* WXBoxShadow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXBoxShadow.m; sourceTree = "<group>"; };
C4F012721E1502A6003378D0 /* SRWebSocket+Weex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SRWebSocket+Weex.h"; sourceTree = "<group>"; };
C4F012731E1502A6003378D0 /* SRWebSocket+Weex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SRWebSocket+Weex.m"; sourceTree = "<group>"; };
C4F012741E1502A6003378D0 /* WXWebSocketDefaultImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXWebSocketDefaultImpl.h; sourceTree = "<group>"; };
@@ -679,6 +687,8 @@
7461F88B1CFB373100F62D44 /* Display */ = {
isa = PBXGroup;
children = (
+ C4D8721F1E5DDEDA00E39BC1 /* WXInnerLayer.m */,
+ C4D872201E5DDEDA00E39BC1 /* WXInnerLayer.h */,
7461F88C1CFB373100F62D44 /* WXDisplayQueue.h */,
7461F88D1CFB373100F62D44 /* WXDisplayQueue.m */,
7461F88E1CFB373100F62D44 /* WXLayer.h */,
@@ -938,6 +948,8 @@
77D161481C02E3670010B15B /* Utility */ = {
isa = PBXGroup;
children = (
+ C4D872231E5DDF7500E39BC1 /* WXBoxShadow.h */,
+ C4D872241E5DDF7500E39BC1 /* WXBoxShadow.m */,
59D3CA481CFC3CE1008835DC /* NSTimer+Weex.h */,
59D3CA491CFC3CE1008835DC /* NSTimer+Weex.m */,
77D161491C02E3790010B15B /* WXConvert.h */,
@@ -1146,6 +1158,8 @@
D362F94F1C83EDA20003F546 /* WXWebViewModule.h in Headers */,
C4F012861E150307003378D0 /* WXWebSocketLoader.h in Headers */,
77D161381C02DE940010B15B /* WXBridgeManager.h in Headers */,
+ C4D872251E5DDF7500E39BC1 /* WXBoxShadow.h in Headers */,
+ C4D872221E5DDEDA00E39BC1 /* WXInnerLayer.h in Headers */,
2A919DA61E321F1F006EB6B5 /* WXBridgeMethod.h in Headers */,
77D161281C02DE1A0010B15B /* WXSDKManager.h in Headers */,
59CE27E81CC387DB000BE37A /* WXEmbedComponent.h in Headers */,
@@ -1468,6 +1482,7 @@
74862F7E1E03A0F300B7A041 /* WXModuleMethod.m in Sources */,
742AD7341DF98C45007DC46C /* WXResourceResponse.m in Sources */,
77E65A161C155EB5008B8775 /* WXTextComponent.m in Sources */,
+ C4D872261E5DDF7500E39BC1 /* WXBoxShadow.m in Sources */,
746319031C60AFC100EFEBD4 /* WXThreadSafeCounter.m in Sources */,
74A4BAA71CB4F98300195969 /* WXStreamModule.m in Sources */,
59597F991D2A041700EE9317 /* WXDebugLoggerBridge.m in Sources */,
@@ -1501,6 +1516,7 @@
744BEA561D05178F00452B5D /* WXComponent+Display.m in Sources */,
7408C48F1CFB345D000BCCD0 /* WXComponent+Events.m in Sources */,
C4F012871E150307003378D0 /* WXWebSocketLoader.m in Sources */,
+ C4D872211E5DDEDA00E39BC1 /* WXInnerLayer.m in Sources */,
745ED2DB1C5F2C7E002DB5A8 /* WXView.m in Sources */,
DC03ADB91D508719003F76E7 /* WXTextAreaComponent.m in Sources */,
59A596231CB6311F0012CD52 /* WXNavigatorModule.m in Sources */,
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/64013ea4/ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.h b/ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.h
new file mode 100644
index 0000000..f3b2bf4
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.h
@@ -0,0 +1,19 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import <Foundation/Foundation.h>
+#import <QuartzCore/QuartzCore.h>
+
+@interface WXInnerLayer : CAGradientLayer
+
+@property CGFloat boxShadowRadius;
+@property CGColorRef boxShadowColor;
+@property CGSize boxShadowOffset;
+@property CGFloat boxShadowOpacity;
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/64013ea4/ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.m b/ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.m
new file mode 100644
index 0000000..fa50867
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Display/WXInnerLayer.m
@@ -0,0 +1,92 @@
+/**
+ * Created by Weex.
+ * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
+ *
+ * This source code is licensed under the Apache Licence 2.0.
+ * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
+ */
+
+#import "WXInnerLayer.h"
+
+@implementation WXInnerLayer
+
+@dynamic boxShadowColor, boxShadowOffset, boxShadowRadius, boxShadowOpacity;
+
+- (id) init {
+ self = [super init];
+ return self;
+}
+
++ (BOOL)needsDisplayForKey:(NSString *)key {
+ if ([key isEqualToString:@"boxShadowRadius"] || [key isEqualToString:@"boxShadowOffset"] || [key isEqualToString:@"boxShadowColor"] || [key isEqualToString:@"boxShadowOpacity"]) {
+ return YES;
+ }
+ return [super needsDisplayForKey:key];
+}
+
+- (id)actionForKey:(NSString *) key {
+ if ([key isEqualToString:@"boxShadowRadius"] || [key isEqualToString:@"boxShadowOffset"] ||[key isEqualToString:@"boxShadowColor"] || [key isEqualToString:@"boxShadowOpacity"] ) {
+ CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:key];
+ theAnimation.fromValue = [self.presentationLayer valueForKey:key];
+ return theAnimation;
+ }
+ return [super actionForKey:key];
+}
+
+- (void)drawInContext:(CGContextRef)context {
+ CGFloat radius = self.cornerRadius;
+
+ CGRect rect = self.bounds;
+ if (self.borderWidth != 0) {
+ rect = CGRectInset(rect, self.borderWidth, self.borderWidth);
+ radius -= self.borderWidth;
+ radius = MAX(radius, 0);
+ }
+
+ CGContextSetAllowsAntialiasing(context, YES);
+ CGContextSetShouldAntialias(context, YES);
+ CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
+ CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
+
+ UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
+ CGContextAddPath(context, bezierPath.CGPath);
+ CGContextClip(context);
+ CGMutablePathRef outer = CGPathCreateMutable();
+ CGPathAddRect(outer, NULL, CGRectInset(rect, -1*rect.size.width, -1*rect.size.height));
+ CGPathAddPath(outer, NULL, bezierPath.CGPath);
+ CGPathCloseSubpath(outer);
+ CGFloat *oldComponents = (CGFloat *)CGColorGetComponents(self.boxShadowColor);
+ CGFloat newComponents[4];
+ NSInteger numberOfComponents = CGColorGetNumberOfComponents(self.boxShadowColor);
+ switch (numberOfComponents)
+ {
+ case 2:
+ {
+ //grayscale
+ newComponents[0] = oldComponents[0];
+ newComponents[1] = oldComponents[0];
+ newComponents[2] = oldComponents[0];
+ newComponents[3] = oldComponents[1] * self.boxShadowOpacity;
+ break;
+ }
+ case 4:
+ {
+ //RGBA
+ newComponents[0] = oldComponents[0];
+ newComponents[1] = oldComponents[1];
+ newComponents[2] = oldComponents[2];
+ newComponents[3] = oldComponents[3] * self.boxShadowOpacity;
+ break;
+ }
+ }
+ CGColorRef shadowColorWithMultipliedAlpha = CGColorCreate(colorspace, newComponents);
+ CGColorSpaceRelease(colorspace);
+ CGContextSetFillColorWithColor(context, shadowColorWithMultipliedAlpha);
+ CGContextSetShadowWithColor(context, self.boxShadowOffset, self.boxShadowRadius, shadowColorWithMultipliedAlpha);
+ CGContextAddPath(context, outer);
+ CGContextEOFillPath(context);
+ CGPathRelease(outer);
+ CGColorRelease(shadowColorWithMultipliedAlpha);
+}
+
+@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/64013ea4/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.h b/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.h
index 6959207..9f8ba62 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.h
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.h
@@ -7,6 +7,7 @@
*/
#import <Foundation/Foundation.h>
+#import "WXInnerLayer.h"
@interface WXBoxShadow : NSObject
@@ -14,7 +15,9 @@
@property CGSize shadowOffset;
@property CGFloat shadowRadius;
@property BOOL isInset;
+@property (nonatomic, strong, nullable)WXInnerLayer *innerLayer;
+@property CGFloat shadowOpacity;
-+(void)configLayer:(UIView *)view boxShadow:(WXBoxShadow *)boxShadow;
-+(WXBoxShadow *)getBoxShadowFromString:(NSString *)string;
++(void)configLayer:(UIView *_Nullable)view boxShadow:(WXBoxShadow *_Nullable)boxShadow;
++(WXBoxShadow *_Nullable)getBoxShadowFromString:(NSString *_Nullable)string;
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/64013ea4/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.m b/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.m
index c1516d7..6362a43 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.m
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXBoxShadow.m
@@ -16,58 +16,95 @@
if(!boxShadow){
return;
}
- UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds];
- view.layer.masksToBounds = NO;
- view.layer.shadowColor = boxShadow.shadowColor;
- view.layer.shadowOffset = boxShadow.shadowOffset;
- view.layer.shadowRadius = boxShadow.shadowRadius;
- view.layer.shadowOpacity = 1.0f;
- view.layer.shadowPath = shadowPath.CGPath;
+ if (boxShadow.isInset) {
+ if (boxShadow.innerLayer) {
+ [boxShadow.innerLayer removeFromSuperlayer];
+ boxShadow.innerLayer.frame = view.bounds;
+ [view.layer addSublayer:boxShadow.innerLayer];
+ }
+ } else {
+ UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds];
+ view.layer.masksToBounds = NO;
+ view.layer.shadowColor = boxShadow.shadowColor;
+ view.layer.shadowOffset = boxShadow.shadowOffset;
+ view.layer.shadowRadius = boxShadow.shadowRadius;
+ view.layer.shadowOpacity = boxShadow.shadowOpacity;
+ view.layer.shadowPath = shadowPath.CGPath;
+ }
}
-+(WXBoxShadow *)getBoxShadowFromString:(NSString *)string
++ (NSArray *)getBoxShadowElementsByBlank:(NSString *)string
{
- NSError *error = nil;
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
+ NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\s{2,}" options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *arr = [regex matchesInString:string options:NSMatchingReportCompletion range:NSMakeRange(0, [string length])];
arr = [[arr reverseObjectEnumerator] allObjects];
-
for (NSTextCheckingResult *str in arr) {
string = [string stringByReplacingCharactersInRange:[str range] withString:@" "];
}
- NSMutableArray *array = [[string componentsSeparatedByString:@" "] mutableCopy];
+ NSArray *array = [string componentsSeparatedByString:@" "];
+ return array;
+}
+
++(WXBoxShadow *)getBoxShadowFromString:(NSString *)string
+{
+ if ([string length] == 0) {
+ return nil;
+ }
+ WXBoxShadow *boxShadow = [WXBoxShadow new];
+ boxShadow.shadowOpacity = 1.0f;
- if (array && [array count] > 0) {
- WXBoxShadow *boxShadow = [WXBoxShadow new];
- if ([@"inset" isEqualToString: array[0]])
+ //parse color
+ if ([string rangeOfString:@"rgb"].location != NSNotFound) {
+ NSRange begin = [string rangeOfString:@"rgb"];
+ NSRange end = [string rangeOfString:@")"];
+ if (begin.location < end.location) {
+ NSRange range = NSMakeRange(begin.location, end.location-begin.location + 1);
+ NSString *str = [string substringWithRange:range];
+ NSString *colorStr = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
+ boxShadow.shadowColor = [WXConvert UIColor:colorStr].CGColor;
+ string = [string stringByReplacingOccurrencesOfString:str withString:@""];// remove color string
+ }
+ } else {
+ NSArray *boxShadowElements = [self getBoxShadowElementsByBlank:string];
+ NSString *str = [boxShadowElements lastObject];
+ boxShadow.shadowColor = [WXConvert UIColor:str].CGColor;
+ string = [string stringByReplacingOccurrencesOfString:str withString:@""];// remove color string
+ }
+
+ // parse remain BoxShadow Elements
+ NSMutableArray *remainBoxShadowElements = [[self getBoxShadowElementsByBlank:string] mutableCopy];
+
+ if (remainBoxShadowElements && [remainBoxShadowElements count] > 0) {
+ if ([@"inset" isEqualToString: remainBoxShadowElements[0]])
{
boxShadow.isInset = YES;
- [array removeObjectAtIndex:0];
+ [remainBoxShadowElements removeObjectAtIndex:0];
}
- for (int i = 0; i < [array count]-1; i++) {
+ for (int i = 0; i < [remainBoxShadowElements count]; i++) {
switch (i) {
case 0:
{
CGSize size = boxShadow.shadowOffset;
- size.width = [WXConvert CGFloat:array[0]];
+ size.width = [WXConvert CGFloat:remainBoxShadowElements[0]];
boxShadow.shadowOffset = size;
}
break;
case 1:
{
CGSize size = boxShadow.shadowOffset;
- size.height = [WXConvert CGFloat:array[1]];
+ size.height = [WXConvert CGFloat:remainBoxShadowElements[1]];
boxShadow.shadowOffset = size;
}
break;
case 2:
{
- boxShadow.shadowRadius = [WXConvert CGFloat:array[2]];
+ boxShadow.shadowRadius = [WXConvert CGFloat:remainBoxShadowElements[2]];
}
break;
@@ -75,10 +112,18 @@
break;
}
}
- boxShadow.shadowColor = [WXConvert UIColor:[array lastObject]].CGColor;
- return boxShadow;
+
+ if (boxShadow.isInset) {
+ if (!boxShadow.innerLayer) {
+ boxShadow.innerLayer = [[WXInnerLayer alloc] init];
+ }
+ boxShadow.innerLayer.boxShadowColor = boxShadow.shadowColor;
+ boxShadow.innerLayer.boxShadowOffset = boxShadow.shadowOffset;
+ boxShadow.innerLayer.boxShadowRadius = boxShadow.shadowRadius;
+ boxShadow.innerLayer.boxShadowOpacity = boxShadow.shadowOpacity;
+ }
}
- return nil;
+ return boxShadow;
}