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;
Tom
quelle
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
    }
}
Stéphane de Luca
quelle
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

Yunus Nedim Mehel
quelle
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)
    }
}
Arbitur
quelle
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
Sergey Belous
quelle
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
Kurt Revis
quelle
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;
}
Johnny Rockex
quelle
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
    }
}
iOS
quelle
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.

reza_khalafi
quelle
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]
pierre23
quelle
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;

quelle
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.

David Barta
quelle
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;
    }
Shakeel Ahmed
quelle
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

Bane M.
quelle
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
        }
    }
}
MrMins
quelle
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.

Nate Symer
quelle
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;
Spydy
quelle
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>
Matt Hudson
quelle
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.

Apouche
quelle
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;
jfmg
quelle
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])
Apinho
quelle
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])
Sanjay Mishra
quelle
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
        }

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

}
Sreeraj VR
quelle
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)
FunkyKat
quelle