Wie setze ich CornerRadius nur für die obere linke und obere rechte Ecke eines UIView?


408

Gibt es eine Möglichkeit, cornerRadiusnur die obere linke und obere rechte Ecke von a UIViewfestzulegen?

Ich habe Folgendes versucht, aber am Ende wird die Ansicht nicht mehr angezeigt.

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
Drei Dinge nach Ihrem bearbeiten, zu beheben: (1) der abgerundeten Pfad basieren sollte view.bounds, nicht frame, (2) sollte die Schicht ein sein CAShapeLayer, nicht CALayer; (3) Stellen Sie die Ebene pathnicht ein shadowPath.
Kurt Revis

1
Mögliches Duplikat dieser Frage & Antwort .
Stuart

Verwenden Sie den Bezier-Kurvenalgorithmus, um Kurven auf einem CGPath zu erstellen. Ich bin mir ziemlich sicher, dass es Teil von CoreGraphics ist. Wenn nicht, hat en.wikipedia.org/wiki/Bézier_curve einige großartige Definitionen und Animationen.
Nate Symer


Siehe meine Antwort hier: stackoverflow.com/a/50396485/6246128
wcarhart

Antworten:


225

Beachten Sie, dass Sie Layoutbeschränkungen in Ihrer UIView-Unterklasse wie folgt aktualisieren müssen:

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

Wenn Sie das nicht tun, wird es nicht angezeigt.


Verwenden Sie zum Abrunden von Ecken die Erweiterung:

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

3
Es ist absolut keine Antwort. Der Autor hat gefragt, wie bestimmte Ecken abgerundet werden sollen und nicht, wie der Eckenradius mit den Layoutänderungen synchronisiert werden soll.
Kelin

1
Diese Antwort macht keinen Sinn.
Tiago Couto

1
Die Antwort wurde vor kurzem behoben .. @kelin
Michael

2
Dies war definitiv um die Ecke.
Aznelite89

Sie müssen dies tun, nachdem die Ansicht erschienen ist
Jonathan.

535

Ich bin nicht sicher, warum Ihre Lösung nicht funktioniert hat, aber der folgende Code funktioniert für mich. Erstellen Sie eine Bezier-Maske und wenden Sie sie auf Ihre Ansicht an. In meinem Code unten habe ich die unteren Ecken des _backgroundViewmit einem Radius von 3 Pixel abgerundet . selfist ein Brauch 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;

Schnelle Version mit einigen Verbesserungen:

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

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

Swift 3.0 Version:

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

Schnelle Erweiterung hier


2
versuchen Sie es im Textfeld. Erfolg links, Misserfolg rechts
Rainer Liao

10
@RainerLiao Ich hatte das gleiche Problem, ich habe das alles auf der viewDidLoadMethode gemacht, es verschoben viewDidAppearund es hat funktioniert.
Lucho

Wie kann ich festlegen, dass dies für jedes Gerät funktioniert? Dies funktioniert nur für die simulatorGröße im Storyboard. ex: if the simulator size is 6s it works fine for 6s, but not of others.Wie kann ich das überwinden?
Chanaka Caldera

1
Kleiner Syntaxfehler in Swift 3 Version: path.CGPathsollte seinpath.cgPath
Rob

@RainerLiao Wenn Sie nicht möchten, dass es beim Anzeigen der Ansicht wechselt, ändern Sie es viewWillAppearstattdessen in. Das funktioniert auch.
Matthew Knippen

263

Hier ist eine Swift- Version der Antwort von @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)

Hinweis

Wenn Sie das automatische Layout verwenden , müssen Sie Ihre Ansicht unterordnen UIViewund roundCornersdie Ansicht aufrufen , layoutSubviewsum einen optimalen Effekt zu erzielen.

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

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

12
Tolle Erweiterung. Allerdings: .TopRightund .BottomRightscheinen nicht für mich zu arbeiten.
Onichan

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

2
Auf der rechten Seite funktioniert es nicht, da die Grenzen Ihrer Ansicht mit Autolayout noch nicht genau definiert sind ... Ich stehe derzeit vor dem gleichen Problem.
Dosdos

3
@dosdos Unterklasse dieser Ansicht und in layoutSubviews um die Ecken von self.
Arbitur

10
Wenn Sie das automatische Layout verwenden und den Verweis auf die Ansicht nicht runden möchten, können Sie .layoutIfNeeded()diese Methode aufrufen .
Zgjie

209

Und schließlich… gibt es CACornerMask in iOS11! Damit CACornerMaskgeht es ganz einfach:

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

1
das funktioniert definitiv am besten. Wir hatten immer Probleme mit den anderen Lösungen, wenn wir die Kanten von Tabellenzellen mit dynamischer Größe abrundeten.
Cornr

2
Das Projekt muss iOS 11 unterstützen, um diese Lösung verwenden zu können.
Aliens

13
@ Aliens und ... das habe ich erwähnt.
Sergey Belous

1
Die anderen Antworten funktionieren beim Drehen des Geräts nicht. Dieser Code funktioniert beim Drehen und ermöglicht das Abrunden bestimmter Ecken. Dies sollte die akzeptierte Antwort sein.
Cloud9999Strife

1
Einfach ist schön
eharo2

99

Schnelles Codebeispiel hier: https://stackoverflow.com/a/35621736/308315


Nicht direkt. Sie müssen:

  1. Ein ... kreieren CAShapeLayer
  2. Stellen Sie pathein, CGPathRefbasierend auf, view.boundsaber mit nur zwei abgerundeten Ecken (wahrscheinlich mit +[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:])
  3. Stellen Sie Ihr view.layer.maskeinCAShapeLayer

21
Seien Sie gewarnt, dies wird die Leistung
beeinträchtigen,

@jjxtra Also, was ist der beste Weg, um es ohne großen Leistungsverlust zu tun? Ich möchte es in UITableViewCell zeigen.
xi.lin

@ xi.lin von dem, woran ich mich erinnere, die Einstellung von layer.shouldRasterize == YES verbessert die Geschwindigkeit ungefähr um das Fünffache . Die Dokumente sagen jedoch, dass es nur funktioniert, wenn Sie mit nicht transparenten Zellen arbeiten. Versuch es einmal.
Codrut

64

Hier ist eine kurze Methode, die wie folgt implementiert ist:

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

Was ist mit dem Einstellen der Farbe? maskLayer.borderWidth = 10; maskLayer.borderColor = [UIColor redColor] .CGColor; Es funktioniert nicht für mich, Sir.
Kiran

1
@ Kiran eine Maske hat keine Farbe, Sie könnten einen zweiten CAShapeLayer hinzufügen, wenn Sie einen Rand haben möchten
Johnny Rockex

25

In Swift 4.1 und Xcode 9.4.1

In iOS 11 reicht diese einzelne Zeile aus:

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

Siehe den vollständigen Code:

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

Aber für niedrigere Versionen

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

Vollständiger Code ist.

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
}

Wenn Sie AutoResizing im Storyboard verwenden, schreiben Sie diesen Code 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
Es funktioniert nicht mit iOS 9, aber mit 11
Ali Ihsan URAL

Irgendeine Lösung für ios 9?
Jey

@jay let rectShape = CAShapeLayer () rectShape.bounds = detailsSubView.frame rectShape.position = detailsSubView.center rectShape.path = UIBezierPath (abgerundet 20, Höhe: 20)). CgPath detailsSubView.layer.mask = rectShape Dieser Code kann für iOS 9
iOS

@ Jay überprüfen, wenn nicht mich informieren
iOS

Funktioniert nicht für ios 9. Es gibt keine Grenze am Eckteil.
Jey

24

iOS 11, Swift 4
Und Sie können diesen Code ausprobieren:

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

Und Sie können dies in der Zelle der Tabellenansicht verwenden.


1
Das ist die richtige Antwort für die heutige Codierung. Tschüss, um die Ebene zu maskieren.
Alen Liang

1
Dies muss die beste Antwort sein!
Fujianjin6471

18

Dies wäre die einfachste Antwort:

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

Tag, dass es die Lösung für iOS 11 oder höher ist
Ankur Lahiry

16

Versuchen Sie diesen Code,

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: .TopRightund .BottomRightarbeiten vielleicht nicht für dich, weil der Anruf view.roundCornerserledigt ist, BEVOR das Finale view boundsberechnet wird. Beachten Sie, dass die Bezier PathAnsicht aus den Ansichtsgrenzen zum Zeitpunkt des Aufrufs stammt. Wenn beispielsweise das automatische Layout die Ansicht einschränkt, befinden sich die runden Ecken auf der rechten Seite möglicherweise außerhalb der Ansicht. Versuchen Sie, es dort aufzurufen viewDidLayoutSubviews, wo die Grenze der Ansicht endgültig ist.


Vielen Dank. Für mich löste das Problem den Aufruf der von "Arbitur" bereitgestellten Implementierung von viewDidLoad und viewWillAppear auf viewDidAppear. Ich könnte dies tun, da mein Steuerelement anfänglich auf versteckt eingestellt ist.
Matti

Du hast recht. Es wird ein Problem mit dem Autolayout verursachen und Sie haben gute Arbeit geleistet.
Ashish Kakkad

15

Swift 4 Swift 5 einfacher Weg in 1 Zeile

Verwendungszweck:

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

Funktion:

//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 Ziel-C

Verwendungszweck:

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

In einer Kategorie verwendete Funktion (nur eine Ecke):

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

Denken Sie nur daran, dass die Ecken Ihrer Ansicht erst berechnet werden, wenn viewDidLayoutSubviews fertig ist. Rufen Sie also roundCorners func auf
Jirson Tavera,

Kannst du sagen, wie ich diesen Ansichten Schatten hinzufügen kann?
Vadlapalli Masthan

@ShakeelAhmed Dies funktioniert nicht, wenn Sie der Ansicht einen Schatten hinzufügen möchten.
Mojtaba al Moussawi

zuerst Eckradius hinzufügen und dann Schatten hinzufügen
Shakeel Ahmed

10

Meine Lösung zum schnellen Abrunden bestimmter Ecken von UIView und UITextFiels ist die Verwendung

.layer.cornerRadius

und

layer.maskedCorners

der tatsächlichen UIView oder UITextFields.

Beispiel:

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
    }

Und mit

.layerMaxXMaxYCorner

und

.layerMaxXMinYCorner

Ich kann die obere rechte und untere rechte Ecke des zu rundenden UITextField angeben.

Sie können das Ergebnis hier sehen:

Geben Sie hier die Bildbeschreibung ein


Perfekt für die Kombination aus Rand und bestimmten Ecken 🎉🎉🎉
Nominierung

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

Sie haben meinen Tag gerettet, in meinem Fall musste ich die Tabellenansicht für bestimmte Zellen runden
Shakti

Perfekt und entsprechend meiner Anforderung. Ich habe die ganze Antwort verwendet, nichts hat bei mir funktioniert, aber Ihre Antwort hat mir geholfen und mein Problem gelöst.
Nikita Patil

6

Eine Möglichkeit, dies programmgesteuert zu tun, besteht darin, einen UIViewüber dem oberen Teil UIViewder abgerundeten Ecken zu erstellen . Oder Sie könnten die Oberseite unter etwas verstecken.


6
Es ist eine sehr hässliche Lösung: 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

Am einfachsten wäre es, eine Maske mit einer abgerundeten Eckschicht zu erstellen.

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

aUIView.layer.mask = maskLayer;

Und vergessen Sie nicht:

#import <QuartzCore/QuartzCore.h>

4

Alle bereits gegebenen Antworten sind wirklich gut und gültig (insbesondere die Idee von Yunus, die zu verwenden mask Eigenschaft zu nutzen).

Ich brauchte jedoch etwas Komplexeres, da meine Ebene häufig die Größe ändern konnte, was bedeutete, dass ich diese Maskierungslogik jedes Mal aufrufen musste, was etwas ärgerlich war.

Ich habe schnelle extensionsund berechnete Eigenschaften verwendet, um eine reale zu erstellencornerRadii die sich um die automatische Aktualisierung der Maske kümmert, wenn die Ebene angelegt wird.

Dies wurde mit Peter Steinberg großen Aspekten erreicht Bibliothek für Swizzling.

Der vollständige Code ist hier:

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 _ { }
    }
  }
}

Ich habe einen einfachen Blog-Beitrag geschrieben , der dies erklärt.



2

So können Sie mit Xamarin in C # einen Eckenradius für jede Ecke einer Schaltfläche festlegen :

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

Eine schöne Erweiterung zur Wiederverwendung der Yunus Nedim Mehel-Lösung

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

Verwendungszweck

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

Schöne saubere Lösung
Aggressor

1

Nach dem Ändern des Code-Bits @apinho In Swift 4.3 funktioniert es einwandfrei

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

So verwenden Sie diese Funktion für Ihre Ansicht

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

0

Eine andere Version von Stephanes Antwort.

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

Erstellen Sie es in Swift 4.2 @IBDesignablewie folgt:

@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

Einfache Erweiterung

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

Verwendungszweck:

view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.