Bagaimana cara mengatur cornerRadius hanya untuk sudut kiri atas dan kanan atas UIView?

408

Apakah ada cara untuk menetapkan cornerRadiushanya sudut kiri atas dan kanan atas UIView?

Saya mencoba yang berikut, tetapi akhirnya tidak melihat pemandangan lagi.

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
sumber
9
Setelah diedit, tiga hal untuk diperbaiki: (1) lintasan bulat harus didasarkan pada view.bounds, bukan frame, (2) layer harus a CAShapeLayer, bukan CALayer; (3) mengatur layer path, bukan shadowPath.
Kurt Revis
1
Kemungkinan duplikat dari pertanyaan & jawaban ini .
Stuart
Gunakan algoritma kurva Bezier, untuk membuat kurva pada CGPath. Saya cukup yakin itu bagian dari CoreGraphics. Jika tidak, en.wikipedia.org/wiki/Bézier_curve memiliki beberapa definisi dan animasi yang bagus.
Nate Symer
Lihat jawaban saya di sini: stackoverflow.com/a/50396485/6246128
wcarhart

Jawaban:

226

Perhatikan fakta bahwa jika Anda memiliki batasan tata letak yang melekat padanya, Anda harus menyegarkan ini sebagai berikut di subkelas UIView Anda:

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

Jika Anda tidak melakukannya, itu tidak akan muncul.


Dan ke sudut-sudut, gunakan ekstensi:

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


Kasing pengontrol tampilan tambahan : Apakah Anda tidak bisa atau tidak ingin membuat subklas tampilan, Anda masih bisa mengitari tampilan. Lakukan dari pengontrol tampilan dengan mengabaikan viewWillLayoutSubviews()fungsi, sebagai berikut:

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)
    }
}
Stéphane de Luca
sumber
3
Ini sama sekali bukan jawaban, penulis bertanya bagaimana membulatkan sudut tertentu, bukan bagaimana menyinkronkan jari-jari sudut dengan perubahan tata letak.
kelin
1
Ini jawaban yang tidak masuk akal.
Tiago Couto
1
jawabannya telah diperbaiki baru-baru ini .. @kelin
Michael
2
ini pasti di tikungan.
aznelite89
Anda harus melakukan ini setelah tampilan muncul
Jonathan.
535

Saya tidak yakin mengapa solusi Anda tidak berhasil tetapi kode berikut ini berfungsi untuk saya. Buat topeng bezier dan terapkan ke tampilan Anda. Dalam kode saya di bawah ini saya membulatkan sudut-sudut bawah _backgroundViewdengan jari-jari 3 piksel. selfadalah kebiasaan 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;

Versi cepat dengan beberapa peningkatan:

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

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

Versi 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

Ekstensi cepat di sini

Yunus Nedim Mehel
sumber
2
coba di bidang teks. sukses di kiri, kegagalan di kanan
Rainer Liao
10
@ TrainLiao saya memiliki masalah yang sama, saya melakukan semua ini pada viewDidLoadmetode, memindahkannya ke viewDidAppeardan itu berhasil.
Lucho
bagaimana cara mengatur ini agar berfungsi untuk perangkat apa pun. ini hanya berfungsi dengan baik untuk simulatorukuran di storyboard. ex: if the simulator size is 6s it works fine for 6s, but not of others.bagaimana saya bisa mengatasinya.
Chanaka Caldera
1
Kesalahan sintaks kecil dalam versi Swift 3: path.CGPathseharusnyapath.cgPath
Rob
@RainerLiao jika Anda tidak ingin mengibaskan saat tampilan muncul, ubahlah menjadi viewWillAppear. Ini juga berfungsi.
Matthew Knippen
263

Ini adalah versi Swift dari jawaban @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)

Catatan

Jika Anda menggunakan Tata Letak Otomatis , Anda harus mensubklasifikasikan Anda UIViewdan memanggil roundCornerstampilan layoutSubviewsuntuk efek optimal.

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

        self.roundCorners([.topLeft, .bottomLeft], radius: 10)
    }
}
Arbitur
sumber
12
Perpanjangan yang bagus. Namun: .TopRightdan .BottomRightsepertinya tidak bekerja untuk saya.
Onichan
4
pada Swift 2 :view.roundCorners([.TopLeft , .BottomLeft], radius: 10)
fahrulazmi
2
Ini tidak berfungsi pada Kanan, karena batas tampilan Anda belum didefinisikan dengan baik dengan autolayout ... Saya saat ini menghadapi masalah yang sama.
dosdos
3
@dosdos Subclass yang melihat dan di layoutSubviews di sekitar sudut diri.
Arbitur
10
Jika Anda menggunakan tata letak otomatis, dan tidak memiliki referensi ke tampilan ingin dibulatkan, Anda dapat memanggil .layoutIfNeeded(), maka metode ini.
zgjie
210

Dan akhirnya ... ada CACornerMask di iOS11! Dengan CACornerMaskitu bisa dilakukan dengan cukup mudah:

let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 10
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Top right corner, Top left corner respectively
Sergey Belous
sumber
1
ini pasti yang terbaik. kami selalu memiliki masalah dengan solusi lain saat membulatkan tepi sel tampilan tabel secara dinamis.
cornr
2
Project harus mendukung iOS 11 dan seterusnya untuk menggunakan solusi itu.
Aliens
13
@Liens dan ... Saya sebutkan itu.
Sergey Belous
1
Jawaban lain tidak berfungsi saat memutar perangkat, kode ini berfungsi untuk rotasi dan memungkinkan Anda untuk berbelok di sudut-sudut tertentu, ini harus menjadi jawaban yang diterima.
Cloud9999Strife
1
Sederhana itu indah
eharo2
99

Contoh kode cepat di sini: https://stackoverflow.com/a/35621736/308315


Tidak secara langsung. Kamu harus:

  1. Membuat CAShapeLayer
  2. Atur pathagar menjadi CGPathRefberdasarkan view.boundstetapi dengan hanya dua sudut bulat (mungkin dengan menggunakan+[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:] )
  3. Tetapkan Anda view.layer.maskuntuk menjadiCAShapeLayer
Kurt Revis
sumber
21
Berhati-hatilah karena ini akan merusak kinerja jika Anda melakukannya di lebih dari beberapa tampilan ...
jjxtra
@ jjxtra Jadi apa cara terbaik untuk melakukannya tanpa banyak kehilangan kinerja? Saya ingin menunjukkannya di UITableViewCell.
xi.lin
@ xi.lin dari apa yang saya ingat pengaturan layer.shouldRasterize == YA meningkatkan kecepatan 5 kali atau lebih. Tetapi dokumen mengatakan itu hanya berfungsi jika Anda bekerja dengan sel yang tidak transparan. Cobalah.
codrut
64

Berikut adalah metode singkat yang diimplementasikan seperti ini:

- (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
sumber
Bagaimana dengan pengaturan warna? maskLayer.borderWidth = 10; maskLayer.borderColor = [UIColor redColor] .CGColor; ini tidak bekerja untuk saya pak.
kiran
1
@kiran topeng tidak memiliki warna, Anda bisa menambahkan CAShapeLayer kedua jika Anda ingin memiliki perbatasan
Johnny Rockex
25

Dalam cepat 4.1 dan Xcode 9.4.1

Di iOS 11 baris tunggal ini sudah cukup:

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

Lihat kode lengkap:

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

Tetapi untuk versi yang lebih rendah

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

Kode lengkapnya adalah.

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
}

Jika Anda menggunakan AutoResizing di storyboard, tulis kode ini di 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
sumber
1
Ini bukan iOS 9 tetapi berfungsi pada 11
Ali Ihsan URAL
Ada solusi untuk ios 9?
jey
@jay let rectShape = CAShapeLayer () rectShape.bounds = detailsSubView.frame rectShape.position = detailsSubView.center rectShape.path = UIBezierPath (roundedRect: detailsSubView.bounds, byRoundingCorners: [.topLeft, .topRg] 20, tinggi: 20)). CgPath detailsSubView.layer.mask = rectShape Kode ini dapat digunakan untuk iOS 9
iOS
@jay periksa apakah tidak memberi tahu saya
iOS
Tidak berfungsi untuk ios 9. Tidak ada perbatasan di bagian sudut.
jey
24

iOS 11, Swift 4
Dan Anda dapat mencoba kode ini:

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

Dan Anda bisa menggunakan ini di sel tampilan tabel.

reza_khalafi
sumber
1
itulah jawaban yang tepat untuk pengkodean hari ini. selamat tinggal untuk menutupi layer.
Alen Liang
1
Ini harus menjadi jawaban terbaik!
fujianjin6471
18

Ini akan menjadi jawaban paling sederhana:

yourView.layer.cornerRadius = 8
yourView.layer.masksToBounds = true
yourView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
pierre23
sumber
tag bahwa itu adalah solusi untuk iOS 11 atau lebih tinggi
Ankur Lahiry
16

Coba kode ini,

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;

sumber
15

Emma: .TopRightdan .BottomRighttidak bekerja untuk Anda mungkin karena panggilan untuk view.roundCornersdilakukan SEBELUM akhir view boundsdihitung. Perhatikan bahwa Bezier Pathturunan berasal dari tampilan terikat pada saat dipanggil. Misalnya, jika tata letak otomatis akan mempersempit tampilan, sudut bundar di sisi kanan mungkin berada di luar tampilan. Coba sebutkan, di viewDidLayoutSubviewsmana batas tampilan adalah final.

David Barta
sumber
Terima kasih. Bagi saya, yang memecahkan masalah adalah memindahkan panggilan ke implementasi yang diberikan oleh "Arbitur" dari viewDidLoad dan viewWillAppear ke viewDidAppear. Saya bisa melakukannya karena kendali saya awalnya disembunyikan.
Matti
Kamu benar. Ini akan menimbulkan masalah dengan autolayout dan Anda telah melakukan pekerjaan dengan baik.
Ashish Kakkad
15

Swift 4 Swift 5 cara mudah dalam 1 baris

Pemakaian:

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

Fungsi:

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

Dalam Objective-C

Pemakaian:

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

Fungsi yang digunakan dalam Kategori (hanya satu sudut):

-(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
sumber
Hanya ingat bahwa sudut-sudut pandangan Anda tidak dihitung sampai viewDidLayoutSubviews selesai sehingga Anda harus memanggil roundCorners func di dalamnya
Jirson Tavera
dapatkah Anda memberi tahu bagaimana cara menambahkan bayangan ke tampilan ini?
Vadlapalli Masthan
@ShakeelAhmed ini tidak akan berfungsi jika Anda ingin menambahkan bayangan ke tampilan.
mojtaba al moussawi
pertama tambahkan radius sudut dan kemudian tambahkan bayangan
Shakeel Ahmed
10

Solusi saya untuk membulatkan sudut-sudut tertentu dari UIView dan UITextFiels dengan cepat adalah menggunakan

.layer.cornerRadius

dan

layer.maskedCorners

UIView atau UITextFields aktual.

Contoh:

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
    }

Dan dengan menggunakan

.layerMaxXMaxYCorner

dan

.layerMaxXMinYCorner

, Saya dapat menentukan sudut kanan atas dan kanan bawah UITextField yang akan dibulatkan.

Anda dapat melihat hasilnya di sini:

masukkan deskripsi gambar di sini

Bane M
sumber
Sempurna untuk kombinasi batas dan sudut tertentu 🎉🎉🎉
nomnom
8

Cepat 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
sumber
Anda menyelamatkan hari saya dalam kasus saya, saya harus membuat tampilan tabel bulat untuk sel
Shakti
Ans sempurna sesuai kebutuhan saya. Saya menggunakan semua jawaban, tidak ada yang berhasil untuk saya, tetapi jawaban Anda membantu saya dan menyelesaikan masalah saya.
Nikita Patil
6

Cara untuk melakukan ini secara terprogram adalah dengan membuat UIViewbagian atas UIViewyang memiliki sudut bulat. Atau Anda bisa menyembunyikan bagian atas di bawah sesuatu.

Nate Symer
sumber
6
Ini solusi yang sangat jelek: 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
sumber
4

Cara termudah adalah membuat topeng dengan lapisan sudut bundar.

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

aUIView.layer.mask = maskLayer;

Dan jangan lupa untuk:

#import <QuartzCore/QuartzCore.h>
Matt Hudson
sumber
4

Semua jawaban yang sudah diberikan benar-benar bagus dan valid (terutama ide Yunus menggunakan maskproperti).

Namun saya membutuhkan sesuatu yang sedikit lebih rumit karena layer saya sering dapat mengubah ukuran yang berarti saya perlu memanggil logika masking itu setiap waktu dan ini sedikit mengganggu.

Saya menggunakan extensionsproperti cepat dan terkomputasi untuk membangun yang nyatacornerRadii properti yang menangani pembaruan otomatis topeng ketika lapisan diletakkan.

Ini dicapai dengan menggunakan Peter Steinberg Great Aspects pustaka untuk bertele-tele.

Kode lengkap ada di sini:

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

Saya menulis posting blog sederhana yang menjelaskan hal ini.

apouche
sumber
2

Ini adalah bagaimana Anda dapat mengatur radius sudut untuk setiap sudut tombol dengan Xamarin di 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;
jfmg
sumber
2

Ekstensi yang bagus untuk menggunakan kembali solusi Yunus Nedim Mehel

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

Pemakaian

let view = UIView()
view.roundCornersWithLayerMask(10,[.TopLeft,.TopRight])
apinho
sumber
Solusi bersih yang bagus
Aggressor
1

Setelah mengubah sedikit kode @apinho In swift 4.3 berfungsi dengan baik

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

Untuk menggunakan fungsi ini untuk Anda lihat

YourViewName. roundCornersWithLayerMask(cornerRadii: 20,corners: [.topLeft,.topRight])
Sanjay Mishra
sumber
0

Versi lain dari jawaban 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
        }

    }
mehdi
sumber
0

Di Swift 4.2, Buat melalui @IBDesignableseperti ini:

@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
sumber
0

Ekstensi sederhana

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

Pemakaian:

view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
FunkyKat
sumber