如何在UIView下绘制阴影?

358

我正在尝试在Cocoa Touch中的UIView下绘制底部的阴影。我了解应该使用CGContextSetShadow()来绘制阴影,但是Quartz 2D编程指南有点含糊:

  1. 保存图形状态。
  2. 调用函数CGContextSetShadow,传递适当的值。
  3. 执行所有要应用阴影的绘图。
  4. 恢复图形状态。

我已经在UIView子类中尝试了以下内容:

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    CGContextRestoreGState(currentContext);
    [super drawRect: rect];
}

但这对我没有用,我有点困惑(a)下一步该怎么做,(b)是否需要对我的UIView做任何处理才能使其工作?

16个回答

3
对于那些在尝试了这里所有的答案之后仍然无法使其工作的人(包括我自己!),请确保“剪切子视图”在属性检查器中未启用...

2
您可以使用我创建的阴影和圆角半径实用函数,如下所示:

- (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];
}

希望能对你有所帮助!!!

1

对于Xamarin开发者,下面是使用Xamarin.iOS/C#的答案:

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();                
}

主要区别在于您获取了一个 CGContext 实例,您可以直接调用适当的方法。

1
所有答案都很好,但我想再补充一点。
如果您在使用表格单元时遇到问题,当您Deque一个新单元时,阴影会不匹配。在这种情况下,您需要将阴影代码放置在layoutSubviews方法中,以便它在所有条件下都能表现良好。
-(void)layoutSubviews{
    [super layoutSubviews];

    [self.contentView setNeedsLayout];
    [self.contentView layoutIfNeeded];
    [VPShadow applyShadowView:self];
}

或者在特定视图控制器中,将阴影代码放入以下方法中,以便其能够正常工作。

-(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;
}

1

Swift 3

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

1
您可以使用此 扩展 添加阴影。
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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接