Jak ustawić cornerRadius tylko dla lewego górnego i prawego górnego rogu UIView?


408

Czy można ustawić cornerRadiustylko lewy górny i prawy górny róg UIView?

Próbowałem następujących, ale ostatecznie nie zobaczyłem widoku.

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
Po zakończeniu edycji należy naprawić trzy rzeczy: (1) zaokrąglona ścieżka powinna opierać się na view.bounds, nie frame, (2) warstwa powinna być, a CAShapeLayernie CALayer; (3) ustaw warstwy path, a nie shadowPath.
Kurt Revis,

1
Możliwe duplikaty tego pytania i odpowiedzi .
Stuart

Użyj algorytmu krzywej Beziera, aby utworzyć krzywe na ścieżce CGPath. Jestem prawie pewien, że to część CoreGraphics. Jeśli nie, en.wikipedia.org/wiki/Bézier_curve ma kilka świetnych definicji i animacji.
Nate Symer


Zobacz moją odpowiedź tutaj: stackoverflow.com/a/50396485/6246128
wcarhart

Odpowiedzi:


224

Zwróć uwagę na fakt, że jeśli masz dołączone ograniczenia układu, musisz odświeżyć to w podklasie UIView w następujący sposób:

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

Jeśli tego nie zrobisz, nie pojawi się.


Aby zaokrąglać rogi, użyj rozszerzenia:

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
Absolutnie nie jest to odpowiedź, autor pytał, jak zaokrąglać poszczególne rogi, a nie jak synchronizować promień narożnika ze zmianami układu.
kelin

1
To odpowiedź nie ma sensu.
Tiago Couto,

1
odpowiedź została ostatnio naprawiona .. @kelin
Michael

2
to zdecydowanie zaokrągliło róg.
aznelite89

Musisz to zrobić po pojawieniu się widoku
Jonathan.

535

Nie jestem pewien, dlaczego twoje rozwiązanie nie działało, ale poniższy kod działa dla mnie. Utwórz maskę Beziera i zastosuj ją do swojego widoku. W poniższym kodzie zaokrąglałem dolne rogi o _backgroundViewpromieniu 3 pikseli. selfto zwyczaj 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;

Wersja szybka z pewnymi ulepszeniami:

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

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

Wersja 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

Szybkie rozszerzenie tutaj


2
spróbuj w polu tekstowym. sukces po lewej, porażka po prawej
Rainer Liao

10
@RainerLiao miałem ten sam problem, zrobiłem to wszystko w viewDidLoadmetodzie, przenieśliłem viewDidAppeari działało.
Lucho,

jak mogę ustawić to, aby działało na dowolnym urządzeniu. działa to dobrze tylko dla simulatorrozmiaru int storyboardu. ex: if the simulator size is 6s it works fine for 6s, but not of others.jak mogę to przezwyciężyć.
Chanaka Caldera

1
Mały błąd składniowy w wersji Swift 3: path.CGPathpowinien byćpath.cgPath
Rob

@RainerLiao, jeśli nie chcesz, aby migotało po wyświetleniu widoku, zmień go na viewWillAppear. To też działa.
Matthew Knippen,

263

Oto Swift wersja @JohnnyRockex odpowiedź

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)

Uwaga

Jeśli używasz automatycznego układu , musisz podklasować UIViewi wywoływać roundCornerswidok, layoutSubviewsaby uzyskać optymalny efekt.

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

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

12
Świetne rozszerzenie. Jednak: .TopRighti .BottomRightwydaje mi się, że nie działa dla mnie.
Onichan,

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

2
To nie działa na prawą stronę, ponieważ granice twojego widoku nie są jeszcze dobrze zdefiniowane przy pomocy autolayout ... Obecnie mam ten sam problem.
dosdos

3
@dosdos Podklasa, która zawiera widok i układ Podglądy za rogami siebie.
Arbitur

10
Jeśli korzystasz z automatycznego układu i nie masz odniesienia do widoku, który chcesz zaokrąglić, możesz wywołać .layoutIfNeeded()tę metodę.
zgjie

209

I wreszcie ... jest CACornerMask w iOS11! Dzięki CACornerMasktemu można to zrobić całkiem łatwo:

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

1
to zdecydowanie działa najlepiej. zawsze mieliśmy problemy z innymi rozwiązaniami podczas zaokrąglania krawędzi dynamicznie zmieniających rozmiar komórek widoku tabeli.
cornr

2
Projekt musi obsługiwać iOS 11 i nowsze, aby móc korzystać z tego rozwiązania.
Aliens

13
@ Aliens i… wspomniałem o tym.
Sergey Belous,

1
Inne odpowiedzi nie działają podczas obracania urządzenia, ten kod działa w przypadku obrotu i pozwala zaokrąglać określone rogi, powinna to być zaakceptowana odpowiedź.
Cloud9999Strife

1
Proste jest piękne
eharo2

99

Przykład szybkiego kodu tutaj: https://stackoverflow.com/a/35621736/308315


Nie bezpośrednio. Będziesz musiał:

  1. Stwórz CAShapeLayer
  2. Ustaw pathjako CGPathRefoparty na, view.boundsale z tylko dwoma zaokrąglonymi narożnikami (prawdopodobnie przy użyciu +[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:])
  3. Ustaw, view.layer.maskaby byćCAShapeLayer

21
Ostrzegamy, że zaszkodzi to wydajności, jeśli zrobisz to na więcej niż kilku widokach ...
jjxtra

@jjxtra Więc jaki jest najlepszy sposób, aby to zrobić bez dużej utraty wydajności? Chcę pokazać to w UITableViewCell.
xi.lin 18.04.16

@ xi.lin z tego co pamiętam ustawienie layer.shouldRasterize == TAK poprawia prędkość około 5 razy. Ale doktorzy mówią, że to działa tylko wtedy, gdy pracujesz z nieprzezroczystymi komórkami. Spróbuj.
codrut

64

Oto krótka metoda zaimplementowana w ten sposób:

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

Co z ustawieniem koloru? maskLayer.borderWidth = 10; maskLayer.borderColor = [UIColor redColor] .CGColor; to dla mnie nie działa.
kiran

1
@kiran maska ​​nie ma koloru, możesz dodać drugą CAShapeLayer, jeśli chcesz mieć obramowanie
Johnny Rockex

25

W wersji szybkiej 4.1 i Xcode 9.4.1

W iOS 11 ta pojedyncza linia wystarczy:

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

Zobacz pełny kod:

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

Ale dla niższych wersji

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

Pełny kod to.

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
}

Jeśli używasz AutoResizing w scenorysie, napisz ten kod w 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
To nie działa iOS 9, ale działa na 11
Ali Ihsan URAL

Jakieś rozwiązanie dla iOS 9?
jey

@jay niech rectShape = CAShapeLayer () rectShape.bounds = detailsSubView.frame rectShape.position = detailsSubView.center rectShape.path = UIBezierPath (roundedRect: detailsSubView.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize 20, wysokość: 20)). CgPath detailsSubView.layer.mask = rectShape Ten kod może działać w systemie iOS 9
iOS

@jay sprawdź, jeśli nie poinformuj mnie
iOS

Nie działa dla iOS 9. Jego nie ma granicy w części narożnej.
jey

24

iOS 11, Swift 4
I możesz wypróbować ten kod:

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

I możesz użyć tego w komórce widoku tabeli.


1
to właściwa odpowiedź na dzisiejsze kodowanie. pa pa do maskowania warstwy.
Alen Liang

1
To musi być najlepsza odpowiedź!
fujianjin6471

18

To byłaby najprostsza odpowiedź:

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

tag, że jest to rozwiązanie dla iOS 11 lub
nowszego

16

Wypróbuj ten kod,

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: .TopRighti .BottomRightnie pracują dla ciebie, być może dlatego, że wezwanie do view.roundCornerszostało wykonane PRZED końcowym view boundsobliczeniem. Zauważ, że Bezier Pathwywodzi się z granic widoku w momencie jego wywołania. Na przykład jeśli automatyczny układ zawęzi widok, zaokrąglone rogi po prawej stronie mogą znajdować się poza widokiem. Spróbuj to nazwać viewDidLayoutSubviews, gdzie granica widoku jest ostateczna.


Dziękuję Ci. Dla mnie rozwiązaniem problemu było przeniesienie wywołania do implementacji podanej przez „Arbitur” z viewDidLoad i viewWillAppear do viewDidAppear. Mógłbym to zrobić, ponieważ początkowo moja kontrola jest ukryta.
Matti,

Masz rację. Stworzy to problem z autolayout i wykonałeś dobrą robotę.
Ashish Kakkad

15

Swift 4 Swift 5 łatwa droga w 1 linii

Stosowanie:

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

Funkcjonować:

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

W celu C

Stosowanie:

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

Funkcja używana w kategorii (tylko jeden róg):

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

Pamiętaj tylko, że narożniki widoku nie są obliczane, dopóki widok viewDidLayoutSubviews nie zostanie zrobiony, więc powinieneś wywołać funkcję roundCorners func wewnątrz niego
Jirson Tavera

czy możesz powiedzieć, jak mogę dodać cień do tych widoków?
Vadlapalli Masthan

@ShakeelAhmed to nie zadziała, jeśli chcesz dodać cień do widoku.
mojtaba al moussawi

najpierw dodaj promień narożnika, a następnie cień
Shakeel Ahmed

10

Moim rozwiązaniem do zaokrąglania określonych narożników UIView i UITextFiels w swift jest użycie

.layer.cornerRadius

i

layer.maskedCorners

rzeczywistych UIView lub UITextFields.

Przykład:

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
    }

I za pomocą

.layerMaxXMaxYCorner

i

.layerMaxXMinYCorner

, Mogę określić prawy górny i prawy dolny róg pola UITextField do zaokrąglenia.

Możesz zobaczyć wynik tutaj:

wprowadź opis zdjęcia tutaj


Idealny do kombinacji granicy i określonych narożników 🎉🎉🎉
nomnom

8

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

Uratowałeś mi dzień w moim przypadku musiałem zaokrąglić widok tabeli dla poszczególnych komórek
Shakti

Idealne i zgodne z moimi wymaganiami. Użyłem całej odpowiedzi, nic nie działało dla mnie, ale twoja odpowiedź pomogła mi i rozwiązała mój problem.
Nikita Patil

6

Sposobem na zrobienie tego programowo byłoby utworzenie UIViewgórnej części z UIViewzaokrąglonymi narożnikami. Lub możesz ukryć górę pod czymś.


6
To bardzo brzydkie rozwiązanie: 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

Najprostszym sposobem byłoby zrobienie maski z zaokrągloną warstwą narożną.

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

aUIView.layer.mask = maskLayer;

I nie zapomnij:

#import <QuartzCore/QuartzCore.h>

4

Wszystkie podane już odpowiedzi są naprawdę dobre i poprawne (szczególnie pomysł Yunusa na użycie mask właściwości).

Potrzebowałem jednak czegoś nieco bardziej złożonego, ponieważ moja warstwa często zmieniała rozmiary, co oznacza, że ​​musiałem nazywać tę logikę maskowania za każdym razem, a to było trochę denerwujące.

Użyłem szybkich extensionsi obliczonych właściwości, aby zbudować prawdziwycornerRadii właściwość, która zajmuje się automatyczną aktualizacją maski po ułożeniu warstwy.

Zostało to osiągnięte dzięki doskonałym aspektom Petera Steinberga biblioteki do zamiatania.

Pełny kod jest tutaj:

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

Wyjaśniłem prosty post na blogu .



2

W ten sposób możesz ustawić promień narożnika dla każdego rogu przycisku za pomocą Xamarin w 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

Piękne rozszerzenie do ponownego wykorzystania rozwiązania 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
} }

Stosowanie

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

Ładne czyste rozwiązanie
Aggressor,

1

Po zmianie bit kodu @apinho W swift 4.3 działa dobrze

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

Aby użyć tej funkcji do przeglądania

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

0

Inna wersja odpowiedzi Stephane'a .

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

W Swift 4.2 utwórz go w @IBDesignablenastępujący sposób:

@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

Proste rozszerzenie

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

Stosowanie:

view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.