How do I draw a shadow under a UIView?
我正试图在一个用可可粉触摸的
我在
1 2 3 4 5 6 7 | - (void)drawRect:(CGRect)rect { CGContextRef currentContext = UIGraphicsGetCurrentContext(); CGContextSaveGState(currentContext); CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5); CGContextRestoreGState(currentContext); [super drawRect: rect]; } |
…但这对我来说不起作用,我有点纠结于(a)下一步该去哪里,(b)如果我需要对我的
一种更简单的方法是在初始化时设置视图的某些层属性:
1 2 3 4 | self.layer.masksToBounds = NO; self.layer.shadowOffset = CGSizeMake(-15, 20); self.layer.shadowRadius = 5; self.layer.shadowOpacity = 0.5; |
你需要进口夸脱。
1 | #import <QuartzCore/QuartzCore.h> |
1 2 3 4 5 | self.layer.masksToBounds = NO; self.layer.cornerRadius = 8; // if you like rounded corners self.layer.shadowOffset = CGSizeMake(-15, 20); self.layer.shadowRadius = 5; self.layer.shadowOpacity = 0.5; |
这将减慢应用程序的速度。添加以下行可以提高性能,只要视图是可见的矩形:
1 | self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath; |
同样的解决方案,但只是提醒您:您可以直接在故事板中定义阴影。
前任:
在当前代码中,保存当前上下文的
任何应该受阴影设置影响的绘图都需要在
1 | CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5); |
但以前
1 | CGContextRestoreGState(currentContext); |
所以,如果你想让超类的
1 2 3 4 5 6 7 | - (void)drawRect:(CGRect)rect { CGContextRef currentContext = UIGraphicsGetCurrentContext(); CGContextSaveGState(currentContext); CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5); [super drawRect: rect]; CGContextRestoreGState(currentContext); } |
你可以试试这个……你可以玩弄价值观。
Swift 2.0
1 2 3 4 5 6 7 8 9 10 11 | let radius: CGFloat = demoView.frame.width / 2.0 //change it to .height if you need spread for height let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 2.1 * radius, height: demoView.frame.height)) //Change 2.1 to amount of spread you need and for height replace the code for height demoView.layer.cornerRadius = 2 demoView.layer.shadowColor = UIColor.blackColor().CGColor demoView.layer.shadowOffset = CGSize(width: 0.5, height: 0.4) //Here you control x and y demoView.layer.shadowOpacity = 0.5 demoView.layer.shadowRadius = 5.0 //Here your control your blur demoView.layer.masksToBounds = false demoView.layer.shadowPath = shadowPath.CGPath |
Swift 3.0
1 2 3 4 5 6 7 8 9 10 11 | let radius: CGFloat = demoView.frame.width / 2.0 //change it to .height if you need spread for height let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 2.1 * radius, height: demoView.frame.height)) //Change 2.1 to amount of spread you need and for height replace the code for height demoView.layer.cornerRadius = 2 demoView.layer.shadowColor = UIColor.black.cgColor demoView.layer.shadowOffset = CGSize(width: 0.5, height: 0.4) //Here you control x and y demoView.layer.shadowOpacity = 0.5 demoView.layer.shadowRadius = 5.0 //Here your control your blur demoView.layer.masksToBounds = false demoView.layer.shadowPath = shadowPath.cgPath |
Example with spread
To create a basic shadow
1 2 3 4 5 | demoView.layer.cornerRadius = 2 demoView.layer.shadowColor = UIColor.blackColor().CGColor demoView.layer.shadowOffset = CGSizeMake(0.5, 4.0); //Here your control your spread demoView.layer.shadowOpacity = 0.5 demoView.layer.shadowRadius = 5.0 //Here your control your blur |
Basic Shadow example in Swift 2.0
使用Interface Builder的简单而干净的解决方案
在项目中添加名为uiview.swift的文件(或将其粘贴到任何文件中):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | import UIKit @IBDesignable extension UIView { /* The color of the shadow. Defaults to opaque black. Colors created * from patterns are currently NOT supported. Animatable. */ @IBInspectable var shadowColor: UIColor? { set { layer.shadowColor = newValue!.CGColor } get { if let color = layer.shadowColor { return UIColor(CGColor:color) } else { return nil } } } /* The opacity of the shadow. Defaults to 0. Specifying a value outside the * [0,1] range will give undefined results. Animatable. */ @IBInspectable var shadowOpacity: Float { set { layer.shadowOpacity = newValue } get { return layer.shadowOpacity } } /* The shadow offset. Defaults to (0, -3). Animatable. */ @IBInspectable var shadowOffset: CGPoint { set { layer.shadowOffset = CGSize(width: newValue.x, height: newValue.y) } get { return CGPoint(x: layer.shadowOffset.width, y:layer.shadowOffset.height) } } /* The blur radius used to create the shadow. Defaults to 3. Animatable. */ @IBInspectable var shadowRadius: CGFloat { set { layer.shadowRadius = newValue } get { return layer.shadowRadius } } } |
然后,在"工具面板>属性检查器"中的每个视图的"界面生成器"中都可以使用该选项:
现在可以轻松设置阴影。
笔记:-阴影不会出现在ib中,只会在运行时出现。-正如Mazen Kasser所说
To those who failed in getting this to work [...] make sure Clip Subviews (
clipsToBounds ) is not enabled
我把它作为实用程序的一部分。这样,我们不仅可以设置阴影,而且可以为任何
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | in utils.m + (void)roundedLayer:(CALayer *)viewLayer radius:(float)r shadow:(BOOL)s { [viewLayer setMasksToBounds:YES]; [viewLayer setCornerRadius:r]; [viewLayer setBorderColor:[RGB(180, 180, 180) CGColor]]; [viewLayer setBorderWidth:1.0f]; if(s) { [viewLayer setShadowColor:[RGB(0, 0, 0) CGColor]]; [viewLayer setShadowOffset:CGSizeMake(0, 0)]; [viewLayer setShadowOpacity:1]; [viewLayer setShadowRadius:2.0]; } return; } |
要使用这个,我们需要称之为-
斯威夫特3
1 2 3 4 5 6 7 8 9 10 11 | extension UIView { func installShadow() { layer.cornerRadius = 2 layer.masksToBounds = false layer.shadowColor = UIColor.black.cgColor layer.shadowOffset = CGSize(width: 0, height: 1) layer.shadowOpacity = 0.45 layer.shadowPath = UIBezierPath(rect: bounds).cgPath layer.shadowRadius = 1.0 } } |
如果您想使用故事板,并且不想继续在运行时属性中键入内容,那么您可以轻松地创建视图的扩展并使它们在故事板中可用。
步骤1。创建扩展名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | extension UIView { @IBInspectable var shadowRadius: CGFloat { get { return layer.shadowRadius } set { layer.shadowRadius = newValue } } @IBInspectable var shadowOpacity: Float { get { return layer.shadowOpacity } set { layer.shadowOpacity = newValue } } @IBInspectable var shadowOffset: CGSize { get { return layer.shadowOffset } set { layer.shadowOffset = newValue } } @IBInspectable var maskToBound: Bool { get { return layer.masksToBounds } set { layer.masksToBounds = newValue } } } |
步骤2。现在可以在Storyboard中使用这些属性。
对于那些没能让这个工作的人(作为我自己!)在这里尝试了所有答案之后,只需确保在属性检查器中没有启用剪辑子视图…
对于其他的Xamarin,答案的xamarin.ios/c版本如下:
1 2 3 4 5 6 7 8 | public override void DrawRect(CGRect area, UIViewPrintFormatter formatter) { CGContext currentContext = UIGraphics.GetCurrentContext(); currentContext.SaveState(); currentContext.SetShadow(new CGSize(-15, 20), 5); base.DrawRect(area, formatter); currentContext.RestoreState(); } |
主要的区别在于,您获取了一个
都回答得很好,但我想再加一分
如果在有表单元格时遇到问题,请取消新单元格阴影中的不匹配,因此在本例中,需要将阴影代码放在layoutSubviews方法中,以便它在所有条件下都能正常工作。
1 2 3 4 5 6 7 | -(void)layoutSubviews{ [super layoutSubviews]; [self.contentView setNeedsLayout]; [self.contentView layoutIfNeeded]; [VPShadow applyShadowView:self]; } |
或者在特定视图的"视图控制器"中,将阴影代码放在下面的方法中,以便其正常工作
1 2 3 4 5 6 | -(void)viewDidLayoutSubviews{ [super viewDidLayoutSubviews]; [self.viewShadow layoutIfNeeded]; [VPShadow applyShadowView:self.viewShadow]; } |
我已经修改了新devs的影子实现,以获得更广泛的形式,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /*! @brief Add shadow to a view. @param layer CALayer of the view. */ +(void)applyShadowOnView:(CALayer *)layer OffsetX:(CGFloat)x OffsetY:(CGFloat)y blur:(CGFloat)radius opacity:(CGFloat)alpha RoundingCorners:(CGFloat)cornerRadius{ UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:layer.bounds cornerRadius:cornerRadius]; layer.masksToBounds = NO; layer.shadowColor = [UIColor blackColor].CGColor; layer.shadowOffset = CGSizeMake(x,y);// shadow x and y layer.shadowOpacity = alpha; layer.shadowRadius = radius;// blur effect layer.shadowPath = shadowPath.CGPath; } |
您可以使用我为阴影和拐角半径创建的实用程序函数,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | - (void)addShadowWithRadius:(CGFloat)shadowRadius withShadowOpacity:(CGFloat)shadowOpacity withShadowOffset:(CGSize)shadowOffset withShadowColor:(UIColor *)shadowColor withCornerRadius:(CGFloat)cornerRadius withBorderColor:(UIColor *)borderColor withBorderWidth:(CGFloat)borderWidth forView:(UIView *)view{ // drop shadow [view.layer setShadowRadius:shadowRadius]; [view.layer setShadowOpacity:shadowOpacity]; [view.layer setShadowOffset:shadowOffset]; [view.layer setShadowColor:shadowColor.CGColor]; // border radius [view.layer setCornerRadius:cornerRadius]; // border [view.layer setBorderColor:borderColor.CGColor]; [view.layer setBorderWidth:borderWidth]; } |
希望它能帮助你!!!!
斯威夫特3
1 2 3 4 | self.paddingView.layer.masksToBounds = false self.paddingView.layer.shadowOffset = CGSize(width: -15, height: 10) self.paddingView.layer.shadowRadius = 5 self.paddingView.layer.shadowOpacity = 0.5 |