【问题标题】:UIView with shadow, rounded corners and custom drawRect带有阴影、圆角和自定义 drawRect 的 UIView
【发布时间】:2014-10-24 19:54:52
【问题描述】:

我必须创建一个自定义的UIView,它将具有圆角、边框、阴影,并且它的drawRect() 方法被覆盖以提供自定义绘图代码,使用该代码将几条直线绘制到视图中(我需要在这里使用快速、轻量级的方法,因为其中许多视图可能会被渲染)。

我目前面临的问题是,一旦我在视图类中覆盖drawRect()(即使其中还没有任何自定义代码),阴影就不再适用于圆角。不同之处见附图:

在视图控制器中,我使用以下代码:

    view.layer.cornerRadius = 10;
    view.layer.masksToBounds = true;

    view.layer.borderColor = UIColor.grayColor().CGColor;
    view.layer.borderWidth = 0.5;

    view.layer.contentsScale = UIScreen.mainScreen().scale;
    view.layer.shadowColor = UIColor.blackColor().CGColor;
    view.layer.shadowOffset = CGSizeZero;
    view.layer.shadowRadius = 5.0;
    view.layer.shadowOpacity = 0.5;
    view.layer.masksToBounds = false;
    view.clipsToBounds = false;

在被覆盖的drawContext() 中,我会使用类似的东西:

    var context:CGContext = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor);
    // Draw them with a 2.0 stroke width so they are a bit more visible.
    CGContextSetLineWidth(context, 2.0);
    CGContextMoveToPoint(context, 0.0, 0.0); //start at this point
    CGContextAddLineToPoint(context, 20.0, 20.0); //draw to this point
    CGContextStrokePath(context);

但是如上所述,即使没有添加此代码,也会出现阴影问题。

除了这种与圆角和阴影兼容的方法之外,还有其他/更好的方法可以将轻量级元素绘制到视图上吗?我不想在视图中添加任何不必要的额外视图或图像上下文,因为它们需要轻巧且高性能。

【问题讨论】:

    标签: ios objective-c uiview swift drawrect


    【解决方案1】:

    这是一个棘手的问题。 UIViewclipsToBounds 是获得圆角所必需的。但是CALayermasksToBounds 必须是false,所以阴影是可见的。不知何故,如果 drawRect 没有被覆盖,一切都会正常工作,但实际上它不应该。

    解决方案是创建一个超级视图来提供阴影(在下面的演示中这是shadowView)。您可以在 Playground 中测试以下内容:

    class MyView : UIView {
        override func drawRect(rect: CGRect) {
            let c = UIGraphicsGetCurrentContext()
            CGContextAddRect(c, CGRectMake(10, 10, 80, 80))
            CGContextSetStrokeColorWithColor(c , UIColor.redColor().CGColor)
            CGContextStrokePath(c)
        }
    }
    
    let superview = UIView(frame: CGRectMake(0, 0, 200, 200))
    
    let shadowView = UIView(frame: CGRectMake(50, 50, 100, 100))
    shadowView.layer.shadowColor = UIColor.blackColor().CGColor
    shadowView.layer.shadowOffset = CGSizeZero
    shadowView.layer.shadowOpacity = 0.5
    shadowView.layer.shadowRadius = 5
    
    let view = MyView(frame: shadowView.bounds)
    view.backgroundColor = UIColor.whiteColor()
    view.layer.cornerRadius = 10.0
    view.layer.borderColor = UIColor.grayColor().CGColor
    view.layer.borderWidth = 0.5
    view.clipsToBounds = true
    
    shadowView.addSubview(view)
    superview.addSubview(shadowView)
    

    结果:

    【讨论】:

    • 谢谢蒙迪!我想无论如何我都无法使用第二个视图来查看阴影。感谢您的解释和代码示例!
    • 解决剪辑到边界和遮罩到边界冲突的好方法
    【解决方案2】:

    我为 UIView 编写了一个小扩展来管理圆角和阴影。 由于变量是@IBInspectable,所以一切都可以直接在storyboard中设置!

    //
    //  UIView extensions.swift
    //
    //  Created by Frédéric ADDA on 25/07/2016.
    //  Copyright © 2016 Frédéric ADDA. All rights reserved.
    //
    
    import UIKit
    
    extension UIView {
    
        @IBInspectable var shadow: Bool {
            get {
                return layer.shadowOpacity > 0.0
            }
            set {
                if newValue == true {
                    self.addShadow()
                }
            }
        }
    
        @IBInspectable var cornerRadius: CGFloat {
            get {
                return self.layer.cornerRadius
            }
            set {
                self.layer.cornerRadius = newValue
    
                // Don't touch the masksToBound property if a shadow is needed in addition to the cornerRadius
                if shadow == false {
                    self.layer.masksToBounds = true
                }
            }
        }
    
    
        func addShadow(shadowColor: CGColor = UIColor.black.cgColor,
                   shadowOffset: CGSize = CGSize(width: 1.0, height: 2.0),
                   shadowOpacity: Float = 0.4,
                   shadowRadius: CGFloat = 3.0) {
            layer.shadowColor = shadowColor
            layer.shadowOffset = shadowOffset
            layer.shadowOpacity = shadowOpacity
            layer.shadowRadius = shadowRadius
        }
    }
    

    这就是它在故事板中的样子:

    结果:

    有一个要求:不要触摸视图上的 clipToBounds(在代码或 IB 中)或图层上的 maskToBound。

    注意:一种情况下它不起作用:tableViews。 由于 UITableView 在后台自动触发 clipToBounds,所以我们不能有阴影。

    编辑:正如 Claudia Fitero 恰当地注意到的那样,您需要在要添加阴影的视图周围留下一个小填充,否则阴影将不可见。 2px-padding 通常就足够了(取决于你的阴影半径)。

    【讨论】:

    • 扩展规则。这是一个巨大的节省时间。谢谢,弗雷德里克!
    • 这对我不起作用,请在另一个线程中查看我的帖子:stackoverflow.com/a/43958505/3052059
    【解决方案3】:

    阴影从视图层内的任何内容中删除。当您禁用裁剪时,整个图层矩形会被默认的backgroundColor 填充,因此阴影也会变成矩形。而不是用圆形蒙版剪裁它,只需使图层的内容变圆,自己绘制它们。而layer的边框是围绕它的边界绘制的,所以你也需要自己绘制。

    例如,在backgroundColor setter 中将实际背景颜色设置为clearColor,并使用drawRect 中传递的颜色来绘制圆角矩形。

    在下面的示例中,我将属性声明为IBInspectable,将整个类声明为IBDesignable,因此可以在情节提要中设置所有内容。这样你甚至可以使用默认的背景选择器来改变你的圆角矩形颜色。

    斯威夫特

    @IBDesignable class RoundRectView: UIView {
    
        @IBInspectable var cornerRadius: CGFloat = 0.0
        @IBInspectable var borderColor: UIColor = UIColor.blackColor()
        @IBInspectable var borderWidth: CGFloat = 0.5
        private var customBackgroundColor = UIColor.whiteColor()
        override var backgroundColor: UIColor?{
            didSet {
                customBackgroundColor = backgroundColor!
                super.backgroundColor = UIColor.clearColor()
            }
        }
    
        func setup() {
            layer.shadowColor = UIColor.blackColor().CGColor;
            layer.shadowOffset = CGSizeZero;
            layer.shadowRadius = 5.0;
            layer.shadowOpacity = 0.5;
            super.backgroundColor = UIColor.clearColor()
        }
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.setup()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            self.setup()
        }
    
        override func drawRect(rect: CGRect) {
            customBackgroundColor.setFill()
            UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius ?? 0).fill()
    
            let borderRect = CGRectInset(bounds, borderWidth/2, borderWidth/2)
            let borderPath = UIBezierPath(roundedRect: borderRect, cornerRadius: cornerRadius - borderWidth/2)
            borderColor.setStroke()
            borderPath.lineWidth = borderWidth
            borderPath.stroke()
    
            // whatever else you need drawn
        }
    }
    

    斯威夫特 3

    @IBDesignable class RoundedView: UIView {
    
    @IBInspectable var cornerRadius: CGFloat = 0.0
    @IBInspectable var borderColor: UIColor = UIColor.black
    @IBInspectable var borderWidth: CGFloat = 0.5
    private var customBackgroundColor = UIColor.white
    override var backgroundColor: UIColor?{
        didSet {
            customBackgroundColor = backgroundColor!
            super.backgroundColor = UIColor.clear
        }
    }
    
    func setup() {
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize.zero
        layer.shadowRadius = 5.0
        layer.shadowOpacity = 0.5
        super.backgroundColor = UIColor.clear
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }
    
    override func draw(_ rect: CGRect) {
        customBackgroundColor.setFill()
        UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius ?? 0).fill()
    
        let borderRect = bounds.insetBy(dx: borderWidth/2, dy: borderWidth/2)
        let borderPath = UIBezierPath(roundedRect: borderRect, cornerRadius: cornerRadius - borderWidth/2)
        borderColor.setStroke()
        borderPath.lineWidth = borderWidth
        borderPath.stroke()
    
        // whatever else you need drawn
    }
    }
    

    Objective-C .h

    IB_DESIGNABLE
    @interface RoundRectView : UIView
    @property IBInspectable CGFloat cornerRadius;
    @property IBInspectable UIColor *borderColor;
    @property IBInspectable CGFloat borderWidth;
    @end
    

    Objective-C .m

    @interface RoundRectView()
    @property UIColor *customBackgroundColor;
    @end
    
    @implementation RoundRectView
    
    -(void)setup{
        self.layer.shadowColor = [UIColor blackColor].CGColor;
        self.layer.shadowOffset = CGSizeZero;
        self.layer.shadowRadius = 5.0;
        self.layer.shadowOpacity = 0.5;
        [super setBackgroundColor:[UIColor clearColor]];
    }
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            [self setup];
        }
        return self;
    }
    
    - (instancetype)initWithCoder:(NSCoder *)coder
    {
        self = [super initWithCoder:coder];
        if (self) {
            [self setup];
        }
        return self;
    }
    
    -(void)setBackgroundColor:(UIColor *)backgroundColor{
        self.customBackgroundColor = backgroundColor;
        super.backgroundColor = [UIColor clearColor];
    }
    
    -(void)drawRect:(CGRect)rect{
        [self.customBackgroundColor setFill];
        [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.cornerRadius] fill];
    
        CGFloat borderInset = self.borderWidth/2;
        CGRect borderRect = CGRectInset(self.bounds, borderInset, borderInset);
        UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:borderRect cornerRadius:self.cornerRadius - borderInset];
        [self.borderColor setStroke];
        borderPath.lineWidth = self.borderWidth;
        [borderPath stroke];
    
        // whatever else you need drawn
    }
    
    @end
    

    Result

    【讨论】:

    • 这实际上是一个更优雅的解决方案!谢谢!
    • @Hodit 谢谢你救了我很多次。谢谢:-)
    • @VaibhavLimbani 很高兴它有帮助:-)
    【解决方案4】:

    这是Hodit's 答案的 swift3 版本,我不得不使用它并在这里找到它并对 XCode 8 进行了一般性更正。像魅力一样工作!

    @IBDesignable class RoundRectView: UIView {
    
    @IBInspectable var cornerRadius: CGFloat = 0.0
    @IBInspectable var borderColor: UIColor = UIColor.black
    @IBInspectable var borderWidth: CGFloat = 0.5
    private var customBackgroundColor = UIColor.white
    override var backgroundColor: UIColor?{
        didSet {
            customBackgroundColor = backgroundColor!
            super.backgroundColor = UIColor.clear
        }
    }
    
    func setup() {
        layer.shadowColor = UIColor.black.cgColor;
        layer.shadowOffset = CGSize.zero
        layer.shadowRadius = 5.0;
        layer.shadowOpacity = 0.5;
        super.backgroundColor = UIColor.clear
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }
    
    override func draw(_ rect: CGRect) {
        customBackgroundColor.setFill()
        UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius ?? 0).fill()
    
        let borderRect = bounds.insetBy(dx: borderWidth/2, dy: borderWidth/2)
        let borderPath = UIBezierPath(roundedRect: borderRect, cornerRadius: cornerRadius - borderWidth/2)
        borderColor.setStroke()
        borderPath.lineWidth = borderWidth
        borderPath.stroke()
    
        // whatever else you need drawn
    }
    }
    

    【讨论】:

    • 是的,确实如此,只需在您的tableViewCell 中提取一个UIView 并从RoundRectView 继承其类。我还没有尝试过,虽然它应该可以工作。
    【解决方案5】:

    我发现以下链接有助于理解设置阴影:

    How to add a shadow to a UIView

    要为 UIVIEW 设置圆角,只需在界面生成器中设置 layer.cornerRadius 值,请查看截图。

    【讨论】:

      【解决方案6】:

      SWIFT 3 解决方案

      改编自蒙迪的回答

      class MyView : UIView {
              override func draw(_ rect: CGRect) {
                  let c = UIGraphicsGetCurrentContext()
                  c!.addRect(CGRect(x: 10, y: 10, width: 80, height: 80))
                  c!.setStrokeColor(UIColor.red.cgColor)
                  c!.strokePath()
              }
          }
      
      let superview = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
      
      let shadowView = UIView(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
      shadowView.layer.shadowColor = UIColor.black.cgColor
      shadowView.layer.shadowOffset = CGSize.zero
      shadowView.layer.shadowOpacity = 0.5
      shadowView.layer.shadowRadius = 5
      
      let view = MyView(frame: shadowView.bounds)
      view.backgroundColor = UIColor.white
      view.layer.cornerRadius = 10.0
      view.layer.borderColor = UIColor.gray.cgColor
      view.layer.borderWidth = 0.5
      view.clipsToBounds = true
      
      shadowView.addSubview(view)
      superview.addSubview(shadowView)
      

      【讨论】:

        【解决方案7】:

        斯威夫特 3

        我做了一个 UIView 扩展,它与 Mundi 建议的想法基本相同:

        extension UIView {
        
        func addShadowView() {
            //Remove previous shadow views
            superview?.viewWithTag(119900)?.removeFromSuperview()
        
            //Create new shadow view with frame
            let shadowView = UIView(frame: frame)
            shadowView.tag = 119900
            shadowView.layer.shadowColor = UIColor.black.cgColor
            shadowView.layer.shadowOffset = CGSize(width: 2, height: 3)
            shadowView.layer.masksToBounds = false
        
            shadowView.layer.shadowOpacity = 0.3
            shadowView.layer.shadowRadius = 3
            shadowView.layer.shadowPath = UIBezierPath(rect: bounds).cgPath
            shadowView.layer.rasterizationScale = UIScreen.main.scale
            shadowView.layer.shouldRasterize = true
        
            superview?.insertSubview(shadowView, belowSubview: self)
        }}
        

        用途:

        class MyCVCell: UICollectionViewCell {
        
        @IBOutlet weak var containerView: UIView!
        
        override func awakeFromNib() {
            super.awakeFromNib()
        }
        
        override func draw(_ rect: CGRect) {
            super.draw(rect)
            containerView.addShadowView()
        }}
        

        【讨论】:

        • 拐角半径怎么样?你什么时候设置的?
        • 并非所有代码都提供了能够得到与上面相同的结果。
        • 谢谢,它正在工作。只需要提到conrerRaidus需要在主视图上设置。圆角半径未链接到阴影。
        • 当方向改变时,阴影不会改变!
        【解决方案8】:

        在 Swift 4.1 中。为了制作 UIView 的圆角,我创建了 UIView 的扩展,如下所示。

        import UIKit
        
        class ViewController: UIViewController {
        
            @IBOutlet weak var viewOuter: UIView!
            @IBOutlet weak var viewInner: UIView!
        
            override func viewDidLoad() {
                super.viewDidLoad()
                viewOuter.backgroundColor = UIColor.clear
                viewInner.roundCorners(15.0)
                viewOuter.addViewShadow()
            }
        }
        extension UIView {
            public func roundCorners(_ cornerRadius: CGFloat) {
                self.layer.cornerRadius = cornerRadius
                self.clipsToBounds = true
                self.layer.masksToBounds = true
            }
        
            public func addViewShadow() {
                DispatchQueue.main.asyncAfter(deadline: (.now() + 0.2)) {
                    let shadowLayer = CAShapeLayer()
                    shadowLayer.path = UIBezierPath(roundedRect: self.bounds, cornerRadius: 15).cgPath
                    shadowLayer.fillColor = UIColor.white.cgColor
        
                    shadowLayer.shadowColor = UIColor.lightGray.cgColor
                    shadowLayer.shadowPath = shadowLayer.path
                    shadowLayer.shadowOffset = CGSize(width: 2.6, height: 2.6)
                    shadowLayer.shadowOpacity = 0.8
                    shadowLayer.shadowRadius = 8.0
                    self.layer.insertSublayer(shadowLayer, at: 0)
                }
            }
        }
        

        【讨论】:

        • 我想你错过了理解这个问题。问题不是关于如何向视图添加角半径,而是如何向圆形角视图添加圆形阴影。更新你的答案:-)
        【解决方案9】:

        解决方案似乎比问题所暗示的要容易得多。我有这个想法,并使用@Hodit 的答案的核心部分来让它发挥作用。实际上,这就是您所需要的:

        - (void) drawRect:(CGRect)rect {
            // make sure the background is set to a transparent color using IB or code
            // e.g.: self.backgroundColor = [UIColor clearColor]; 
        
            // draw a rounded rect in the view
            [[UIColor whiteColor] setFill];
            [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:5.0] fill];
        
            // apply shadow if you haven't already
            self.layer.masksToBounds = NO;
            self.layer.shadowColor = [[UIColor blackColor] CGColor];
            self.layer.shadowOffset = CGSizeMake(0.0,3.0);
            self.layer.shadowRadius= 1.0;
            self.layer.shadowOpacity = 0.1;
        
            // more code here
        
        }
        

        请注意,这不会剪切子视图。视图中位于 0,0 的任何内容都将与可见的左上角圆角重叠。

        【讨论】:

          【解决方案10】:

          我用这个扩展来UIView:

          Import UIKit
          
          extension UIView {
              
              /// A property that accesses the backing layer's opacity.
              @IBInspectable
              open var opacity: Float {
                  get {
                      return layer.opacity
                  }
                  set(value) {
                      layer.opacity = value
                  }
              }
              
              /// A property that accesses the backing layer's shadow
              @IBInspectable
              open var shadowColor: UIColor? {
                  get {
                      guard let v = layer.shadowColor else {
                          return nil
                      }
                      
                      return UIColor(cgColor: v)
                  }
                  set(value) {
                      layer.shadowColor = value?.cgColor
                  }
              }
              
              /// A property that accesses the backing layer's shadowOffset.
              @IBInspectable
              open var shadowOffset: CGSize {
                  get {
                      return layer.shadowOffset
                  }
                  set(value) {
                      layer.shadowOffset = value
                  }
              }
              
              /// A property that accesses the backing layer's shadowOpacity.
              @IBInspectable
              open var shadowOpacity: Float {
                  get {
                      return layer.shadowOpacity
                  }
                  set(value) {
                      layer.shadowOpacity = value
                  }
              }
              
              /// A property that accesses the backing layer's shadowRadius.
              @IBInspectable
              open var shadowRadius: CGFloat {
                  get {
                      return layer.shadowRadius
                  }
                  set(value) {
                      layer.shadowRadius = value
                  }
              }
              
              /// A property that accesses the backing layer's shadowPath.
              @IBInspectable
              open var shadowPath: CGPath? {
                  get {
                      return layer.shadowPath
                  }
                  set(value) {
                      layer.shadowPath = value
                  }
              }
              
              
              /// A property that accesses the layer.cornerRadius.
              @IBInspectable
              open var cornerRadius: CGFloat {
                  get {
                      return layer.cornerRadius
                  }
                  set(value) {
                      layer.cornerRadius = value
                  }
              }
              
              
              /// A property that accesses the layer.borderWith.
              @IBInspectable
              open var borderWidth: CGFloat {
                  get {
                      return layer.borderWidth
                  }
                  set(value) {
                      layer.borderWidth = value
                  }
              }
              
              /// A property that accesses the layer.borderColor property.
              @IBInspectable
              open var borderColor: UIColor? {
                  get {
                      guard let bcolor = layer.borderColor else {
                          return nil
                      }
                      return UIColor(cgColor: bcolor)
                  }
                  set(value) {
                      layer.borderColor = value?.cgColor
                  }
              }
          }
          

          【讨论】:

            【解决方案11】:

            试试这个对我有用...

                yourView.layer.shadowColor = UIColor.blackColor().CGColor
                yourView.layer.shadowOpacity = 0.5
                yourView.layer.shadowOffset = CGSize(width: 3, height: 3)
                yourView.layer.shadowRadius = 05
            
                yourView.layer.shadowPath = UIBezierPath(rect: yourView.bounds).CGPath
                yourView.layer.shouldRasterize = true
            

            【讨论】:

            • 有效!这很棒,因为它是一个很小的解决方案。就我而言,虽然就在边界之外,但它看起来有点小而粗糙。
            【解决方案12】:

            在斯威夫特。对我有用的是添加:

                self.noteImage.layer.masksToBounds = false
            

            所以,完整的代码是:

                self.noteImage.layer.masksToBounds = false
                self.noteImage.layer.shadowColor = UIColor.redColor().CGColor
                self.noteImage.layer.shadowOpacity = 0.5
                self.noteImage.layer.shadowOffset = CGSize(width: 2, height: 2)
                self.noteImage.layer.shadowRadius = 1
            
                self.noteImage.layer.shadowPath = UIBezierPath(rect: noteImage.bounds).CGPath
                self.noteImage.layer.shouldRasterize = true
            

            【讨论】:

            • 不确定你在哪里设置视图的圆角半径属性,因为这是主要问题。
            【解决方案13】:

            除了 Frederic Adda 的解决方案之外,不要忘记将具有阴影的视图定位到可以绘制阴影的超级视图的填充。否则阴影将被剪掉。 我在自定义单元格中犯了这个错误,并认为解决方案是错误的,直到我在周围添加了 8px 的填充。

            【讨论】:

              【解决方案14】:

              这是我的解决方案。如果您有多种类型的视图,如 UIView、UIControl、UITableView 等,并且不想为每个视图创建子类,或者您想通过对代码的最小更改来添加此效果,那么这可能就是您想要的正在寻找。

              Objective-C.h

              #import <UIKit/UIKit.h>
              
              @interface UIView (CornerAndShadow)
              
              - (void)setCornerAndShadow;
              
              @end
              

              Objective-C.m

              #import "UIView+CornerAndShadow.h"
              #import <Masonry.h>
              
              @implementation UIView (CornerAndShadow)
              
              - (void)setCornerAndShadow {
                  // constants
                  CGFloat fCornerRadius = 9.f;
              
                  // only work for views with superview
                  if (self.superview == nil) {
                      return;
                  }
              
                  // set corner
                  self.layer.cornerRadius = fCornerRadius;
                  self.layer.masksToBounds = YES;
              
                  // create and configure shadowView
                  UIView *shadowView = [UIView new];
                  shadowView.backgroundColor = self.backgroundColor; // just to make shadow visible
                  shadowView.layer.cornerRadius = fCornerRadius;
                  shadowView.layer.shadowColor = [UIColor redColor].CGColor;
                  shadowView.layer.shadowOffset = CGSizeMake(0, 3.f);
                  shadowView.layer.shadowOpacity = 0.5f;
                  shadowView.layer.shadowRadius = 5.f;
              
                  // put shadowView into superview right below self
                  [self.superview insertSubview:shadowView belowSubview:self];
              
                  // set shadowView's frame equal to self
                  [shadowView mas_makeConstraints:^(MASConstraintMaker *make) {
                      make.edges.equalTo(self);
                  }];
                  // use this if you're not using autolayout, and can get real frame here
                  // shadowView.frame = self.frame;
              }
              
              @end
              

              【讨论】:

                【解决方案15】:

                这是一个较老的问题,但我会在您的自定义绘制方法中完成所有操作,如下所示。

                如果我知道我想在圆形视图上应用阴影,我通常会这样做(这当然意味着我不想使用masksToBounds

                您也不必向层次结构添加额外的“阴影视图”。

                @IBDesignable
                class RoundedView: UIView {
                
                @IBInspectable
                var cornerRadius: CGFloat = 0
                
                override func draw(_ rect: CGRect) {
                    guard let context = UIGraphicsGetCurrentContext() else { return }
                    // You could use custom IBInspectable attributes
                    // for the stroke and fill color.
                    context.setFillColor(UIColor.white.cgColor)
                    context.setStrokeColor(UIColor.orange.cgColor)
                    // Add a clipping path to get the rounded look
                    // you want.
                    UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).addClip()
                    // Fill and stroke your background.
                    let background = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
                    background.lineWidth = 2
                    background.fill()
                    background.stroke()
                }
                
                private func shadow() {
                    layer.shadowColor = UIColor.black.cgColor
                    layer.shadowRadius = 5
                    layer.shadowOpacity = 0.5
                    layer.shadowOffset = CGSize.zero
                }
                
                override func awakeFromNib() {
                    super.awakeFromNib()
                    shadow()
                }
                }
                

                【讨论】:

                  【解决方案16】:

                  您可以将此功能用于所有视图。

                      extension UIView{
                  
                      func radiusAndBorder(radius:CGFloat, color:UIColor = UIColor.clear) -> UIView{
                          var rounfView:UIView = self
                          rounfView.layer.cornerRadius = CGFloat(radius)
                          rounfView.layer.borderWidth = 1
                          rounfView.layer.borderColor = color.cgColor
                          rounfView.clipsToBounds = true
                          return rounfView
                      }
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 2011-06-12
                    • 2012-07-11
                    • 2014-09-15
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多