UIView avec ombre, coins arrondis et drawRect personnalisé

Je dois créer un UIView personnalisé qui aura des coins ronds, une bordure, une ombre et sa méthode drawRect() est remplacée pour fournir un code de dessin personnalisé avec lequel plusieurs lignes droites sont dessinées dans la vue (je dois utiliser une approche rapide et légère ici car beaucoup de ces vues peuvent être rendues).

Le problème auquel je suis actuellement confronté est que l'ombre ne s'applique plus aux coins ronds dès que je remplace drawRect() dans la classe view (même sans code personnalisé encore dans il). Voir l'image ci-jointe pour la différence:

entrez la description de l'image ici

Dans le contrôleur de vue, j'utilise le code suivant:

    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;

Dans le drawContext() remplacé, j'utiliserais quelque chose comme:

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

Mais comme indiqué ci-dessus, le problème de l'ombre se produit même sans ce code ajouté.

Existe-t-il un autre/meilleur moyen de dessiner des éléments légers sur une vue autre que cette approche compatible avec les coins ronds et les ombres? Je ne veux pas ajouter de vues supplémentaires inutiles ou des contextes d'image à la vue car ceux-ci doivent être légers et performants.

44
demandé sur Mundi 2014-08-31 15:10:09

16 réponses

C'est délicat. UIView's clipsToBounds est nécessaire pour obtenir des coins arrondis. Mais CALayer's masksToBounds doit être false, donc l'ombre est visible. D'une certaine manière, tout fonctionne si drawRect n'est pas remplacé, mais en fait il ne devrait pas.

La solution consiste à créer un superview pour fournir l'ombre (dans la démonstration ci-dessous c'est le shadowView). Vous pouvez tester ce qui suit dans 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)

Résultat:

entrez la description de l'image ici

88
répondu Mundi 2014-08-31 12:19:48

J'ai écrit Une petite extension à UIView pour gérer les coins arrondis et l'ombre portée. Comme les variables sont @IBInspectable, tout peut être réglé directement dans le 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
    }
}

Et voici à quoi cela ressemble dans le storyboard : storyboard

Le résultat : entrez la description de l'image ici

Il y a une exigence: Ne touchez ni clipToBounds sur la vue (dans le code ou dans IB) ni masksToBound sur le calque.

NB: un cas dans lequel cela ne fonctionnera pas : tableViews. Comme UITableView déclenche automatiquement clipToBounds sous le capot, nous ne pouvons pas avoir d'ombre portée.

EDIT: comme Claudia Fitero l'a bien remarqué, vous devez laisser un petit remplissage autour de la vue à laquelle vous ajoutez une ombre, sinon l'ombre ne sera pas visible. Un rembourrage 2px suffit généralement (en fonction de votre rayon d'ombre).

40
répondu Frédéric Adda 2018-05-26 07:17:04

L'ombre est supprimée de tout ce qui se trouve à l'intérieur du calque de la vue. Lorsque vous désactivez l'écrêtage, le rectangle de calque entier est rempli par défaut backgroundColor de sorte que l'ombre devient également rectangulaire. Au lieu de l'écrêter avec un masque arrondi, faites simplement arrondir le contenu du calque, dessinez-le vous-même. Et la bordure de layer est dessinée autour de ses limites, vous devez donc la dessiner vous-même.

Par exemple, dans backgroundColor setter, définissez la couleur d'arrière-plan réelle sur clearColor et utilisez la couleur passée dans drawRect pour dessiner un rect arrondi avec.

Dans l'exemple ci-dessous, je déclare les propriétés comme IBInspectable et toute la classe comme IBDesignable, donc tout peut être défini dans storyboard. De cette façon, vous pouvez même utiliser le sélecteur d'arrière-plan par défaut pour changer votre couleur rect arrondie.

Swift

@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
    }
}

Swift 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
}
}

Objectif-C.h

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

Objectif-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

Résultat

16
répondu Hodit 2017-12-20 02:35:37

Voici la version swift3 de la réponse de Hodit , j'ai dû l'utiliser et l'ai trouvée ici et j'ai fait des corrections générales pour XCode 8. Fonctionne comme le charme!

@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
}
}
8
répondu amagain 2016-08-15 11:38:57

Swift 3

J'ai fait une extension UIView et c'est fondamentalement la même idée suggérée par 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)
}}

Utilisation:

class MyCVCell: UICollectionViewCell {

@IBOutlet weak var containerView: UIView!

override func awakeFromNib() {
    super.awakeFromNib()
}

override func draw(_ rect: CGRect) {
    super.draw(rect)
    containerView.addShadowView()
}}

Résultat

4
répondu xlsmearlx 2017-08-23 18:50:00

Solution SWIFT 3

Adapté de la réponse de Mundi

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)
3
répondu Oscar 2017-02-22 08:13:52

Je trouve le lien suivant utile pour comprendre le réglage du dropshadow:

Comment ajouter une ombre à un UIView

Pour définir le coin rond pour UIVIEW, il suffit de définir la valeur layer.cornerRadius dans Interface builder, veuillez vérifier la capture d'écran. entrez la description de l'image ici

3
répondu Zulqarnain 2017-06-29 05:27:54

La solution semble beaucoup plus facile que le problème pourrait suggérer. J'ai eu ceci avec un de mes points de vue et utilisé la partie centrale de la réponse de @Hodit pour le faire fonctionner. C'est tout ce dont vous avez besoin en fait:

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

}

Notez que cela ne coupe pas les sous-vues. Tout ce qui est positionné à 0,0 dans la vue chevauchera le coin arrondi supérieur gauche visible.

1
répondu ar34z 2016-07-28 10:20:48

Essayez ceci c'est du travail pour moi...

    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
1
répondu Piyush Sanepara 2016-08-12 05:40:52

Dans Swift. Ce qui a fonctionné pour moi a été d'ajouter:

    self.noteImage.layer.masksToBounds = false

Donc, le code complet est:

    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
1
répondu Maria Ortega 2016-08-31 11:10:47

En plus de la solution de Frederic Adda, n'oubliez pas de positionner la vue qui a shadow avec un remplissage à la superview, où l'ombre peut être dessinée. Sinon, l'ombre sera coupée. J'ai fait cette erreur dans ma cellule personnalisée, et je pensais que la solution était fausse jusqu'à ce que j'ajoute un remplissage de 8px tout autour.

1
répondu Claudia Fitero 2016-11-15 13:09:49

C'est ma solution. Si vous avez plusieurs types de vues comme UIView, UIControl, UITableView et ainsi de suite, et que vous ne voulez pas créer de sous-classes de chacune d'elles, ou si vous voulez ajouter cet effet avec les plus petites modifications à votre code, alors c'est peut-être ce que vous recherchez.

Objectif-C. H

#import <UIKit/UIKit.h>

@interface UIView (CornerAndShadow)

- (void)setCornerAndShadow;

@end

Objectif-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
1
répondu arthurdai 2016-12-09 08:25:33

J'utilise cette extension 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
répondu MBH 2017-07-20 09:21:24

C'est une question plus ancienne, mais j'aurais tout fait dans votre méthode de tirage personnalisée comme ci-dessous.

Je le ferai généralement si je sais que je veux appliquer une ombre portée à ma vue arrondie (ce qui signifie Bien sûr que je ne veux pas utiliser masksToBounds)

Vous n'avez pas non plus besoin d'ajouter une "vue d'ombre" supplémentaire à la hiérarchie.

@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()
}
}
0
répondu WBuck 2018-06-07 12:00:38

Dans Swift 4.1. Pour faire le coin arrondi de UIView j'ai créé L'Extension de UIView comme suit.

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

entrez la description de l'image ici entrez la description de l'image ici

0
répondu GSK 2018-09-22 17:16:00

Vous pouvez utiliser cette fonction pour toutes vos vues.

    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
    }
}
-1
répondu SwiftyIso 2017-03-20 11:39:12