Come impostare cornerRadius solo per l'angolo superiore sinistro e superiore destro di una vista UIV?


408

C'è un modo per impostare cornerRadiussolo l'angolo in alto a sinistra e in alto a destra di un UIView?

Ho provato quanto segue, ma alla fine non ho più visto la vista.

UIView *view = [[UIView alloc] initWithFrame:frame];

CALayer *layer = [CALayer layer];
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight) cornerRadii:CGSizeMake(3.0, 3.0)];
layer.shadowPath = shadowPath.CGPath;
view.layer.mask = layer;

9
Dopo la modifica, tre cose da correggere: (1) il percorso arrotondato dovrebbe essere basato view.bounds, non frame, (2) il livello dovrebbe essere un CAShapeLayer, no CALayer; (3) imposta il livello path, no shadowPath.
Kurt Revis,

1
Possibile duplicato di questa domanda e risposta .
Stuart,

Utilizzare l'algoritmo della curva di Bezier per creare curve su un CGPath. Sono abbastanza sicuro che faccia parte di CoreGraphics. In caso contrario, en.wikipedia.org/wiki/Bézier_curve ha alcune definizioni e animazioni eccezionali.
Nate Symer


Vedere la mia risposta qui: stackoverflow.com/a/50396485/6246128
wcarhart

Risposte:


226

Fai attenzione al fatto che se hai vincoli di layout associati, devi aggiornarlo come segue nella sottoclasse UIView:

override func layoutSubviews() {
    super.layoutSubviews()
    roundCorners(corners: [.topLeft, .topRight], radius: 3.0)
}

Se non lo fai, non verrà visualizzato.


E per arrotondare gli angoli, usa l'estensione:

extension UIView {
   func roundCorners(corners: UIRectCorner, radius: CGFloat) {
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        layer.mask = mask
    }
}


Caso del controller di visualizzazione aggiuntivo : se non puoi o non vuoi sottoclassare una vista, puoi comunque arrotondare una vista. Fallo dal suo controller di vista ignorando la viewWillLayoutSubviews()funzione, come segue:

class MyVC: UIViewController {
    /// The view to round the top-left and top-right hand corners
    let theView: UIView = {
        let v = UIView(frame: CGRect(x: 10, y: 10, width: 200, height: 200))
        v.backgroundColor = .red
        return v
    }()

    override func loadView() {
        super.loadView()
        view.addSubview(theView)
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        // Call the roundCorners() func right there.
        theView.roundCorners(corners: [.topLeft, .topRight], radius: 30)
    }
}

3
Non è assolutamente una risposta, l'autore chiedeva come arrotondare angoli particolari, non come sincronizzare il raggio degli angoli con le modifiche del layout.
Kelin

1
Questa è la risposta non ha senso.
Tiago Couto,

1
la risposta è stata corretta di recente .. @kelin
Michael

2
questo ha sicuramente arrotondato l'angolo.
aznelite89,

Devi farlo dopo che è apparso il punto di vista
Jonathan.

535

Non sono sicuro del motivo per cui la tua soluzione non ha funzionato, ma il seguente codice funziona per me. Crea una maschera più bezier e applicala alla tua vista. Nel mio codice in basso stavo arrotondando gli angoli inferiori della _backgroundViewcon un raggio di 3 pixel. selfè un'usanza UITableViewCell:

UIBezierPath *maskPath = [UIBezierPath
    bezierPathWithRoundedRect:self.backgroundImageView.bounds
    byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight)
    cornerRadii:CGSizeMake(20, 20)
];

CAShapeLayer *maskLayer = [CAShapeLayer layer];

maskLayer.frame = self.bounds;
maskLayer.path = maskPath.CGPath;

self.backgroundImageView.layer.mask = maskLayer;

Versione rapida con alcuni miglioramenti:

let path = UIBezierPath(roundedRect:viewToRound.bounds, byRoundingCorners:[.TopRight, .BottomLeft], cornerRadii: CGSizeMake(20, 20))
let maskLayer = CAShapeLayer()

maskLayer.path = path.CGPath
viewToRound.layer.mask = maskLayer

Versione Swift 3.0:

let path = UIBezierPath(roundedRect:viewToRound.bounds,
                        byRoundingCorners:[.topRight, .bottomLeft],
                        cornerRadii: CGSize(width: 20, height:  20))

let maskLayer = CAShapeLayer()

maskLayer.path = path.cgPath
viewToRound.layer.mask = maskLayer

Rapida estensione qui


2
prova nel campo di testo. successo a sinistra, fallimento a destra
Rainer Liao

10
@RainerLiao ho avuto lo stesso problema, ho fatto tutto questo sul viewDidLoadmetodo, spostalo viewDidAppeare ha funzionato.
Lucho,

come posso impostare questo per funzionare su qualsiasi dispositivo. funziona bene solo per le simulatordimensioni dello storyboard. ex: if the simulator size is 6s it works fine for 6s, but not of others.come posso superare questo.
Chanaka Caldera,

1
Piccolo errore di sintassi nella versione di Swift 3: path.CGPathdovrebbe esserepath.cgPath
Rob,

@RainerLiao se non vuoi che scorra mentre appare la vista, cambialo viewWillAppearinvece. Questo funziona anche.
Matthew Knippen,

263

Ecco una versione Swift della risposta @JohnnyRockex

extension UIView {

    func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
         let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
         let mask = CAShapeLayer()
         mask.path = path.cgPath
         self.layer.mask = mask
    }

}

view.roundCorners([.topLeft, .bottomRight], radius: 10)

Nota

Se stai utilizzando il layout automatico , dovrai sottoclassare il tuo UIViewe chiamare roundCornersnella vista layoutSubviewsper un effetto ottimale.

class View: UIView {
    override func layoutSubviews() {
        super.layoutSubviews()

        self.roundCorners([.topLeft, .bottomLeft], radius: 10)
    }
}

12
Grande estensione. Tuttavia: .TopRighte .BottomRightnon sembra funzionare per me.
Onichan,

4
su Swift 2 :view.roundCorners([.TopLeft , .BottomLeft], radius: 10)
fahrulazmi,

2
Non funziona a destra, perché i limiti della vista non sono ancora ben definiti con il completamento automatico ... Attualmente sto affrontando lo stesso problema.
dosdos,

3
@dosdos Sottoclasse che visualizza e nel layout Sottoviste agli angoli di sé.
Arbitur,

10
Se si utilizza il layout automatico e non si ha il riferimento alla vista che si desidera arrotondare, è possibile chiamare .layoutIfNeeded(), quindi questo metodo.
zgjie,

210

E infine ... c'è CACornerMask in iOS11! Con CACornerMaskesso può essere fatto abbastanza facile:

let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 10
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Top right corner, Top left corner respectively

1
questo sicuramente funziona meglio. abbiamo sempre avuto problemi con le altre soluzioni durante l'arrotondamento dei bordi delle celle di visualizzazione tabella con dimensionamento dinamico.
cornr,

2
Il progetto deve supportare iOS 11 e versioni successive per utilizzare quella soluzione.
Alieni

13
@Aliens e ... l'ho detto.
Sergey Belous,

1
Le altre risposte non funzionano quando si ruota il dispositivo, questo codice funziona per la rotazione e consente di arrotondare determinati angoli, questa dovrebbe essere la risposta accettata.
Cloud9999 sciopero

1
Simple is beautiful
eharo2,

99

Esempio di codice Swift qui: https://stackoverflow.com/a/35621736/308315


Non direttamente Tu dovrai:

  1. Creare un CAShapeLayer
  2. Imposta il suo pathcome CGPathRefbasato su view.boundsma con solo due angoli arrotondati (probabilmente usando +[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:])
  3. Imposta il tuo view.layer.maskper essere ilCAShapeLayer

21
Tieni presente che questo danneggerà le prestazioni se lo fai in più di un paio di visualizzazioni ...
jjxtra,

@jjxtra Quindi qual è il modo migliore per farlo senza troppe perdite di prestazioni? Voglio mostrarlo in UITableViewCell.
xi.lin,

@ xi.lin da quello che ricordo di aver impostato layer.shouldRasterize == SÌ migliora la velocità di circa 5 volte. Ma i documenti dicono che funziona solo se lavori con celle non trasparenti. Dagli Un colpo.
codrut,

64

Ecco un breve metodo implementato in questo modo:

- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton *openInMaps = [UIButton new];
    [openInMaps setFrame:CGRectMake(15, 135, 114, 70)];
    openInMaps = (UIButton *)[self roundCornersOnView:openInMaps onTopLeft:NO topRight:NO bottomLeft:YES bottomRight:NO radius:5.0];
}

- (UIView *)roundCornersOnView:(UIView *)view onTopLeft:(BOOL)tl topRight:(BOOL)tr bottomLeft:(BOOL)bl bottomRight:(BOOL)br radius:(float)radius {

    if (tl || tr || bl || br) {
        UIRectCorner corner = 0;
        if (tl) {corner = corner | UIRectCornerTopLeft;}
        if (tr) {corner = corner | UIRectCornerTopRight;}
        if (bl) {corner = corner | UIRectCornerBottomLeft;}
        if (br) {corner = corner | UIRectCornerBottomRight;}

        UIView *roundedView = view;
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:roundedView.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)];
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.frame = roundedView.bounds;
        maskLayer.path = maskPath.CGPath;
        roundedView.layer.mask = maskLayer;
        return roundedView;
    }
    return view;
}

Che dire dell'impostazione del colore? maskLayer.borderWidth = 10; maskLayer.borderColor = [UIColor redColor] .CGColor; non funziona per me signore.
Kiran,

1
@kiran una maschera non ha un colore, potresti aggiungere un secondo CAShapeLayer se vuoi avere un bordo
Johnny Rockex,

25

In rapido 4.1 e Xcode 9.4.1

In iOS 11 questa linea singola è sufficiente:

detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]//Set your view here

Vedi il codice completo:

//In viewDidLoad
if #available(iOS 11.0, *){
        detailsSubView.clipsToBounds = false
        detailsSubView.layer.cornerRadius = 10
        detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
} else {
      //For lower versions
}

Ma per le versioni inferiori

let rectShape = CAShapeLayer()
    rectShape.bounds = detailsSubView.frame
    rectShape.position = detailsSubView.center
    rectShape.path = UIBezierPath(roundedRect: detailsSubView.bounds,    byRoundingCorners: [.topLeft , .topRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
    detailsSubView.layer.mask = rectShape

Il codice completo è.

if #available(iOS 11.0, *){
    detailsSubView.clipsToBounds = false
    detailsSubView.layer.cornerRadius = 10
    detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
}else{
    let rectShape = CAShapeLayer()
    rectShape.bounds = detailsSubView.frame
    rectShape.position = detailsSubView.center
    rectShape.path = UIBezierPath(roundedRect: detailsSubView.bounds,    byRoundingCorners: [.topLeft , .topRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
    detailsSubView.layer.mask = rectShape
}

Se si utilizza il ridimensionamento automatico nello storyboard, scrivere questo codice in viewDidLayoutSubviews () .

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if #available(iOS 11.0, *){
        detailsSubView.clipsToBounds = false
        detailsSubView.layer.cornerRadius = 10
        detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
    }else{
        let rectShape = CAShapeLayer()
        rectShape.bounds = detailsSubView.frame
        rectShape.position = detailsSubView.center
        rectShape.path = UIBezierPath(roundedRect: detailsSubView.bounds,    byRoundingCorners: [.topLeft , .topRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
        detailsSubView.layer.mask = rectShape
    }
}

1
Non funziona iOS 9 ma funziona su 11
Ali Ihsan URAL

Qualche soluzione per iOS 9?
jey,

@jay let rectShape = CAShapeLayer () rectShape.bounds = detailsSubView.frame rectShape.position = detailsSubView.center rectShape.path = UIBezierPath (RoundRect: detailsSubView.bounds, byRoundingCorners: [.topLeft,. 20, altezza: 20)). CgPath detailsSubView.layer.mask = rectShape Questo codice può funzionare per iOS 9
iOS

@jay controlla se non mi informa
iOS

Non funziona per iOS 9. Non c'è bordo sulla parte d'angolo.
jey,

24

iOS 11, Swift 4
E puoi provare questo codice:

if #available(iOS 11.0, *) {
   element.clipsToBounds = true
   element.layer.cornerRadius = CORNER_RADIUS
   element.layer.maskedCorners = [.layerMaxXMaxYCorner]
} else {
   // Fallback on earlier versions
}

E puoi usarlo nella cella della vista tabella.


1
questa è la risposta giusta per la codifica di oggi. ciao ciao per mascherare il livello.
Alen Liang,

1
Questa deve essere la risposta migliore!
fujianjin6471,

18

Questa sarebbe la risposta più semplice:

yourView.layer.cornerRadius = 8
yourView.layer.masksToBounds = true
yourView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]

tag che è la soluzione per iOS 11 o superiore
Ankur Lahiry

16

Prova questo codice,

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:( UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(5.0, 5.0)];

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.view.bounds;
maskLayer.path  = maskPath.CGPath;

view.layer.mask = maskLayer;

15

Emma: .TopRighte .BottomRightnon stanno funzionando per te forse perché la chiamata a view.roundCornersè fatta PRIMA della finale view boundssono calcolati. Si noti che Bezier Pathderiva dai limiti della vista nel momento in cui viene chiamato. Ad esempio, se il layout automatico restringe la vista, gli angoli arrotondati sul lato destro potrebbero essere esterni alla vista. Prova a chiamarlo viewDidLayoutSubviews, dove il limite della vista è definitivo.


Grazie. Per me, ciò che ha risolto il problema è stato spostare la chiamata all'implementazione fornita da "Arbitur" da viewDidLoad e viewWillAppear per viewDidAppear. Potrei farlo poiché il mio controllo inizialmente è impostato su nascosto.
Matti,

Hai ragione. Creerà problemi con il completamento automatico e hai fatto un buon lavoro.
Ashish Kakkad,

15

Swift 4 Swift 5 modo semplice in 1 riga

Uso:

//MARK:- Corner Radius of only two side of UIViews
self.roundCorners(view: yourview, corners: [.bottomLeft, .topRight], radius: 12.0)

Funzione:

//MARK:- Corner Radius of only two side of UIViews
func roundCorners(view :UIView, corners: UIRectCorner, radius: CGFloat){
        let path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        view.layer.mask = mask
}

In Objective-C

Uso:

[self.verticalSeparatorView roundCorners:UIRectCornerTopLeft radius:10.0];

Funzione utilizzata in una categoria (solo un angolo):

-(void)roundCorners: (UIRectCorner) corners radius:(CGFloat)radius {
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
        CAShapeLayer *mask = [[CAShapeLayer alloc] init];
        mask.path = path.CGPath;
        self.layer.mask = mask;
    }

Ricorda solo che gli angoli della tua vista non vengono calcolati fino a quando viewDidLayoutSubviews non viene eseguito, quindi dovresti chiamare roundCorners func al suo interno
Jirson Tavera,

puoi dire come posso aggiungere l'ombra a queste viste?
Vadlapalli Masthan,

@ShakeelAhmed non funzionerà se si desidera aggiungere un'ombra alla vista.
Mojtaba al Moussawi,

prima aggiungi il raggio dell'angolo e poi aggiungi l'ombra
Shakeel Ahmed

10

La mia soluzione per arrotondare angoli specifici di UIView e UITextFiels in un attimo è usare

.layer.cornerRadius

e

layer.maskedCorners

di UIView o UITextField effettivi.

Esempio:

fileprivate func inputTextFieldStyle() {
        inputTextField.layer.masksToBounds = true
        inputTextField.layer.borderWidth = 1
        inputTextField.layer.cornerRadius = 25
        inputTextField.layer.maskedCorners = [.layerMaxXMaxYCorner,.layerMaxXMinYCorner]
        inputTextField.layer.borderColor = UIColor.white.cgColor
    }

E usando

.layerMaxXMaxYCorner

e

.layerMaxXMinYCorner

, Posso specificare l'angolo superiore destro e inferiore destro di UITextField da arrotondare.

Puoi vedere il risultato qui:

inserisci qui la descrizione dell'immagine


Perfetto per la combinazione di bordi e angoli specifici 🎉🎉🎉
nomnom

8

Swift 4

extension UIView {

    func roundTop(radius:CGFloat = 5){
        self.clipsToBounds = true
        self.layer.cornerRadius = radius
        if #available(iOS 11.0, *) {
            self.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
        } else {
            // Fallback on earlier versions
        }
    }

    func roundBottom(radius:CGFloat = 5){
        self.clipsToBounds = true
        self.layer.cornerRadius = radius
        if #available(iOS 11.0, *) {
            self.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner]
        } else {
            // Fallback on earlier versions
        }
    }
}

Mi hai salvato la giornata nel mio caso, ho dovuto arrotondare la vista del tavolo per celle particolari
Shakti,

Perfetto e secondo il mio requisito. Ho usato tutta la risposta, niente ha funzionato per me, ma la tua risposta mi ha aiutato e risolto il mio problema.
Nikita Patil,

6

Un modo per farlo a livello di codice sarebbe quello di creare una UIViewparte superiore UIViewche ha gli angoli arrotondati. Oppure potresti nascondere la parte superiore sotto qualcosa.


6
È una soluzione molto brutta: P
Arbitur

6
    // Create the path (with only the top-left corner rounded)
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds 
                           byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) 
                           cornerRadii:CGSizeMake(7.0, 7.0)];

// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = cell.stripBlackImnageView.bounds;
maskLayer.path = maskPath.CGPath; 
// Set the newly created shapelayer as the mask for the image view's layer
view.layer.mask = maskLayer;

4

Il modo più semplice sarebbe quello di creare una maschera con uno strato angolare arrotondato.

CALayer *maskLayer = [CALayer layer];
maskLayer.frame = CGRectMake(0,0,maskWidth ,maskHeight);
maskLayer.contents = (__bridge id)[[UIImage imageNamed:@"maskImageWithRoundedCorners.png"] CGImage];

aUIView.layer.mask = maskLayer;

E non dimenticare di:

#import <QuartzCore/QuartzCore.h>

4

Tutte le risposte già fornite sono davvero valide e valide (in particolare l'idea di Yunus di utilizzare la maskproprietà).

Tuttavia, avevo bisogno di qualcosa di un po 'più complesso perché il mio layer poteva spesso cambiare dimensione, il che significa che dovevo chiamare ogni volta quella logica di mascheramento e questo era un po' fastidioso.

Ho usato extensionsproprietà rapide e calcolate per costruire una cornerRadiiproprietà reale che si occupa dell'aggiornamento automatico della maschera quando il layer è disposto.

Ciò è stato ottenuto utilizzando la grande libreria Aspects di Peter Steinberg per sfrigolare.

Il codice completo è qui:

extension CALayer {
  // This will hold the keys for the runtime property associations
  private struct AssociationKey {
    static var CornerRect:Int8 = 1    // for the UIRectCorner argument
    static var CornerRadius:Int8 = 2  // for the radius argument
  }

  // new computed property on CALayer
  // You send the corners you want to round (ex. [.TopLeft, .BottomLeft])
  // and the radius at which you want the corners to be round
  var cornerRadii:(corners: UIRectCorner, radius:CGFloat) {
    get {
      let number = objc_getAssociatedObject(self, &AssociationKey.CornerRect)  as? NSNumber ?? 0
      let radius = objc_getAssociatedObject(self, &AssociationKey.CornerRadius)  as? NSNumber ?? 0
      return (corners: UIRectCorner(rawValue: number.unsignedLongValue), radius: CGFloat(radius.floatValue))
    }
    set (v) {
      let radius = v.radius
      let closure:((Void)->Void) = {
        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: v.corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.CGPath
        self.mask = mask
      }
      let block: @convention(block) Void -> Void = closure
      let objectBlock = unsafeBitCast(block, AnyObject.self)
      objc_setAssociatedObject(self, &AssociationKey.CornerRect, NSNumber(unsignedLong: v.corners.rawValue), .OBJC_ASSOCIATION_RETAIN)
      objc_setAssociatedObject(self, &AssociationKey.CornerRadius, NSNumber(float: Float(v.radius)), .OBJC_ASSOCIATION_RETAIN)
      do { try aspect_hookSelector("layoutSublayers", withOptions: .PositionAfter, usingBlock: objectBlock) }
      catch _ { }
    }
  }
}

Ho scritto un semplice post sul blog spiegando questo.



2

Ecco come puoi impostare un raggio d'angolo per ogni angolo di un pulsante con Xamarin in C # :

var maskPath = UIBezierPath.FromRoundedRect(MyButton.Bounds, UIRectCorner.BottomLeft | UIRectCorner.BottomRight,
    new CGSize(10.0, 10.0));
var maskLayer = new CAShapeLayer
{
    Frame = MyButton.Bounds,
    Path = maskPath.CGPath
};
MyButton.Layer.Mask = maskLayer;

2

Una deliziosa estensione per riutilizzare la soluzione Yunus Nedim Mehel

Swift 2.3

extension UIView {
func roundCornersWithLayerMask(cornerRadii: CGFloat, corners: UIRectCorner) {
    let path = UIBezierPath(roundedRect: bounds,
                            byRoundingCorners: corners,
                            cornerRadii: CGSize(width: cornerRadii, height: cornerRadii))
    let maskLayer = CAShapeLayer()
    maskLayer.path = path.CGPath
    layer.mask = maskLayer
} }

uso

let view = UIView()
view.roundCornersWithLayerMask(10,[.TopLeft,.TopRight])

Bella soluzione pulita
Aggressor

1

Dopo aver cambiato bit di codice @apinho In swift 4.3 funziona bene

extension UIView {
func roundCornersWithLayerMask(cornerRadii: CGFloat, corners: UIRectCorner) {
    let path = UIBezierPath(roundedRect: bounds,
                            byRoundingCorners: corners,
                            cornerRadii: CGSize(width: cornerRadii, height: cornerRadii))
    let maskLayer = CAShapeLayer()
    maskLayer.path = path.cgPath
    layer.mask = maskLayer
  }
}

Per utilizzare questa funzione per la visualizzazione

YourViewName. roundCornersWithLayerMask(cornerRadii: 20,corners: [.topLeft,.topRight])

0

Un'altra versione della risposta di Stephane .

import UIKit

    class RoundCornerView: UIView {
    var corners : UIRectCorner = [.topLeft,.topRight,.bottomLeft,.bottomRight]
        var roundCornerRadius : CGFloat = 0.0
        override func layoutSubviews() {
            super.layoutSubviews()
            if corners.rawValue > 0 && roundCornerRadius > 0.0 {
                self.roundCorners(corners: corners, radius: roundCornerRadius)
            }
        }
        private func roundCorners(corners: UIRectCorner, radius: CGFloat) {
            let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            layer.mask = mask
        }

    }

0

In Swift 4.2, crealo in @IBDesignablequesto modo:

@IBDesignable

class DesignableViewCustomCorner: UIView {

    @IBInspectable var cornerRadious: CGFloat = 0 {
        didSet {
            let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: cornerRadious, height: cornerRadious))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            self.layer.mask = mask
        }
    }

}

0

Estensione semplice

extension UIView {
    func roundCorners(corners: UIRectCorner, radius: CGFloat) {
        if #available(iOS 11, *) {
            self.clipsToBounds = true
            self.layer.cornerRadius = radius
            var masked = CACornerMask()
            if corners.contains(.topLeft) { masked.insert(.layerMinXMinYCorner) }
            if corners.contains(.topRight) { masked.insert(.layerMaxXMinYCorner) }
            if corners.contains(.bottomLeft) { masked.insert(.layerMinXMaxYCorner) }
            if corners.contains(.bottomRight) { masked.insert(.layerMaxXMaxYCorner) }
            self.layer.maskedCorners = masked
        }
        else {
            let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            layer.mask = mask
        }
    }
}

Uso:

view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.