我试图在Cocoa Touch的UIView的底部边缘下画一个阴影。我知道我应该使用CGContextSetShadow()来绘制阴影,但Quartz 2D编程指南有点模糊:
保存图形状态。
调用CGContextSetShadow函数,传递适当的值。
执行要应用阴影的所有绘图。
恢复图形状态
我已经尝试了以下在一个UIView子类:
- (void)drawRect:(CGRect)rect {
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(currentContext);
CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
CGContextRestoreGState(currentContext);
[super drawRect: rect];
}
..但是这对我来说不工作,我有点卡住了(a)下一步要去哪里(b)如果我需要对我的UIView做什么来让这个工作?
你可以试试这个....你可以调整数值。
阴影半径决定了模糊的数量。shadowOffset指定阴影的位置。
斯威夫特2.0
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
斯威夫特3.0
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
关于传播的例子
创建一个基本的阴影
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
Swift 2.0中的基本Shadow示例
答得很好,但我想再补充一点
如果你遇到一个问题,当你有表格单元格,Deque一个新单元格有一个不匹配的阴影,所以在这种情况下,你需要把你的阴影代码在一个layoutSubviews方法,这样它将在所有条件下表现良好。
-(void)layoutSubviews{
[super layoutSubviews];
[self.contentView setNeedsLayout];
[self.contentView layoutIfNeeded];
[VPShadow applyShadowView:self];
}
或者在ViewControllers中为特定的视图放置阴影代码在下面的方法中,这样它就能很好地工作
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[self.viewShadow layoutIfNeeded];
[VPShadow applyShadowView:self.viewShadow];
}
我已经修改了我的影子实现为新的开发更普遍的形式,例如:
/*!
@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;
}
你可以使用这个扩展来添加阴影
extension UIView {
func addShadow(offset: CGSize, color: UIColor, radius: CGFloat, opacity: Float)
{
layer.masksToBounds = false
layer.shadowOffset = offset
layer.shadowColor = color.cgColor
layer.shadowRadius = radius
layer.shadowOpacity = opacity
let backgroundCGColor = backgroundColor?.cgColor
backgroundColor = nil
layer.backgroundColor = backgroundCGColor
}
}
你可以称之为
your_Custom_View.addShadow(offset: CGSize(width: 0, height: 1), color: UIColor.black, radius: 2.0, opacity: 1.0)
在当前代码中,保存当前上下文的GState,配置为绘制阴影。然后将其恢复到您配置它绘制阴影之前的状态。然后,最后,调用超类的drawRect:的实现。
任何应该受到阴影设置影响的绘图都需要在之后进行
CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
但在
CGContextRestoreGState(currentContext);
如果你想要超类的drawRect:被“包装”在阴影中,那么如果你像这样重新安排你的代码呢?
- (void)drawRect:(CGRect)rect {
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(currentContext);
CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
[super drawRect: rect];
CGContextRestoreGState(currentContext);
}