UIView with shadow, rounded corners and custom drawRect

前端 未结 16 1282
南旧
南旧 2020-12-02 05:22

I have to create a custom UIView that will have round corners, a border, a shadow and its drawRect() method is overridden to provide custom drawing

相关标签:
16条回答
  • 2020-12-02 05:50

    I find the following link helpful to understand setting the dropshadow:

    How to add a shadow to a UIView

    To set the round corner for UIVIEW just set the layer.cornerRadius value in interface builder, Please check screenshot.

    0 讨论(0)
  • 2020-12-02 05:52

    you can use this function for your all views.

        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
        }
    }
    
    0 讨论(0)
  • 2020-12-02 05:55

    I wrote a small extension to UIView to manage both rounded corners AND drop shadow. As the variables are @IBInspectable, everything can be set directly in the 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
        }
    }
    

    And this is how it looks in the storyboard :

    The result :

    There is one requirement : DON'T touch either clipToBounds on the view (in code or in IB) or masksToBound on the layer.

    NB: one case in which it won't work : tableViews. As UITableView automatically triggers clipToBoundsunder the hood, we can't have a drop shadow.

    EDIT: as Claudia Fitero aptly noticed, you need to leave a small padding around the view to which you are adding a shadow, otherwise the shadow won't be visible. A 2px-padding is enough generally (depending on your shadow radius).

    0 讨论(0)
  • 2020-12-02 05:55

    Swift 3

    I made an UIView extension and its basically the same idea suggested by 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)
    }}
    

    Use:

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

    0 讨论(0)
  • 2020-12-02 05:57

    SWIFT 3 Solution

    Adapted from Mundi's answer

    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)
    
    0 讨论(0)
  • 2020-12-02 06:00

    I use this extension to 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 v = layer.borderColor else {
                    return nil
                }
                return UIColor(cgColor: v)
            }
            set(value) {
                layer.borderColor = value?.cgColor
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题