Làm cách nào để đặt gócRadius chỉ cho góc trên cùng bên trái và trên cùng bên phải của một UIView?


408

Có cách nào để chỉ đặt cornerRadiusgóc trên cùng bên trái và trên cùng bên phải của a UIViewkhông?

Tôi đã thử như sau, nhưng cuối cùng không thấy được cảnh nào nữa.

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
Sau khi chỉnh sửa, ba điều cần khắc phục: (1) đường dẫn được làm tròn nên dựa trên view.bounds, không frame, (2) lớp nên là a CAShapeLayer, không CALayer; (3) đặt lớp path, không shadowPath.
Kurt Revis

1
Có thể trùng lặp câu hỏicâu trả lời này .
Stuart

Sử dụng thuật toán đường cong Bezier, để tạo các đường cong trên CGPath. Tôi khá chắc chắn rằng đó là một phần của CoreGraphics. Nếu không, en.wikipedia.org/wiki/Bézier_curve có một số định nghĩa và hình ảnh động tuyệt vời.
Symate Nate


Xem câu trả lời của tôi ở đây: stackoverflow.com/a/50394485/6246128
wcarhart

Câu trả lời:


225

Hãy chú ý đến thực tế là nếu bạn có các ràng buộc về bố cục kèm theo nó, bạn phải làm mới điều này như sau trong lớp con UIView của bạn:

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

Nếu bạn không làm điều đó, nó sẽ không xuất hiện.


Và để góc tròn, sử dụng phần mở rộng:

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
Đây hoàn toàn không phải là một câu trả lời, tác giả đã hỏi cách làm tròn các góc cụ thể, không phải cách đồng bộ hóa bán kính góc với thay đổi bố cục.
kelin

1
Đây là câu trả lời không có ý nghĩa.
Tiago Couto

1
câu trả lời đã được sửa gần đây .. @kelin
Michael

2
Điều này chắc chắn làm tròn góc.
aznelite89

Bạn phải làm điều này sau khi quan điểm đã xuất hiện
Jonathan.

535

Tôi không chắc tại sao giải pháp của bạn không hoạt động nhưng đoạn mã sau đang hoạt động với tôi. Tạo mặt nạ bezier và áp dụng nó vào chế độ xem của bạn. Trong mã của tôi bên dưới, tôi đã làm tròn các góc dưới cùng _backgroundViewvới bán kính 3 pixel. selflà một phong tục 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;

Phiên bản Swift với một số cải tiến:

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

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

Phiên bản 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

Mở rộng Swift tại đây


2
thử trong trường văn bản. thành công ở bên trái, thất bại ở bên phải
Rainer Liao

10
@RainerLiao tôi có cùng một vấn đề, tôi đã làm tất cả điều này trên viewDidLoadphương thức, chuyển nó sang viewDidAppearvà nó hoạt động.
Lucho

Làm thế nào tôi có thể thiết lập điều này để làm việc cho bất kỳ thiết bị. Điều này chỉ hoạt động tốt cho simulatorkích thước int bảng phân cảnh. ex: if the simulator size is 6s it works fine for 6s, but not of others.Làm thế nào tôi có thể vượt qua điều này.
Chanaka Caldera

1
Lỗi cú pháp nhỏ trong phiên bản Swift 3: path.CGPathnênpath.cgPath
Rob

@RainerLiao nếu bạn không muốn nó nhấp nháy khi chế độ xem xuất hiện, thay đổi nó thành viewWillAppearthay thế. Điều này cũng hoạt động.
Matthew Knippen

263

Đây là phiên bản Swift của câu trả lời @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)

Ghi chú

Nếu bạn đang sử dụng Bố cục tự động , bạn sẽ cần phân lớp UIViewvà gọi roundCornerstrong chế độ xem layoutSubviewsđể có hiệu quả tối ưu.

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

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

12
Mở rộng tuyệt vời. Tuy nhiên: .TopRight.BottomRightdường như không làm việc cho tôi.
Onichan

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

2
Nó không hoạt động ở bên phải, vì giới hạn của chế độ xem của bạn chưa được xác định rõ khi tự động thanh toán ... Tôi hiện đang đối mặt với cùng một vấn đề.
dosdos

3
@dosdos Lớp con xem và trong layoutSubview quanh các góc của bản thân.
Arbitur

10
Nếu bạn sử dụng bố cục tự động và không tham chiếu đến chế độ xem muốn làm tròn, bạn có thể gọi .layoutIfNeeded(), sau đó phương thức này.
zgjie

209

Và cuối cùng là có CACornerMask trong iOS11! Với CACornerMasknó có thể được thực hiện khá dễ dàng:

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

1
Điều này chắc chắn hoạt động tốt nhất. chúng tôi luôn gặp vấn đề với các giải pháp khác khi làm tròn các cạnh của các ô xem bảng kích thước động.
cornr

2
Dự án phải hỗ trợ iOS 11 trở đi để sử dụng giải pháp đó.
Người ngoài hành tinh

13
@Aliens và tầm tôi đã đề cập đến điều đó.
Serge Belous

1
Các câu trả lời khác không hoạt động khi xoay thiết bị, mã này hoạt động để xoay và cho phép bạn làm tròn một số góc nhất định, đây sẽ là câu trả lời được chấp nhận.
Cloud9999Strife

1
Đơn giản là đẹp
eharo2

99

Ví dụ về mã Swift tại đây: https://stackoverflow.com/a/35621736/308315


Không trực tiếp. Bạn sẽ phải:

  1. Tạo một CAShapeLayer
  2. Đặt nó paththành một CGPathRefdựa trên view.boundsnhưng chỉ có hai góc tròn (có thể bằng cách sử dụng +[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:])
  3. Đặt bạn view.layer.maskCAShapeLayer

21
Được cảnh báo rằng điều này sẽ làm giảm hiệu suất nếu bạn thực hiện nó trên nhiều hơn chỉ là một vài lượt xem ...
jjxtra

@jjxtra Vậy cách tốt nhất để làm điều đó mà không làm giảm hiệu suất? Tôi muốn hiển thị nó trong UITableViewCell.
xi.lin

@ xi.lin từ những gì tôi nhớ cài đặt layer.shouldRasterize == CÓ cải thiện tốc độ 5 lần hoặc hơn. Nhưng các tài liệu nói rằng nó chỉ hoạt động nếu bạn làm việc với các ô không trong suốt. Cho nó một shot.
codrut

64

Đây là một phương pháp ngắn được thực hiện như thế này:

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

Màu cài đặt thì sao? maskLayer.borderWidth = 10; maskLayer.borderColor = [UIColor redColor] .CGColor; nó không làm việc cho tôi
kiran

1
@kiran mặt nạ không có màu, bạn có thể thêm CAShapeLayer thứ hai nếu bạn muốn có đường viền
Johnny Rockex

25

Trong swift 4.1 và Xcode 9.4.1

Trong iOS 11 , dòng đơn này là đủ:

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

Xem mã hoàn chỉnh:

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

Nhưng đối với phiên bản thấp hơn

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

Mã hoàn chỉnh là.

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
}

Nếu bạn đang sử dụng AutoResizing trong bảng phân cảnh, hãy viết mã này trong viewDidLayoutSubview () .

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
Nó không hoạt động iOS 9 nhưng hoạt động vào ngày 11
Ali Ihsan URAL

Giải pháp nào cho ios 9?
Jey

@jay let orthShape = CAShapeLayer () orthShape.bound = chi tiếtSubView.frame orthShape.poseition = chi tiết 20, chiều cao: 20)). CgPath chi tiếtSubView.layer.mask = orthShape Mã này có thể hoạt động cho iOS 9
iOS

@jay kiểm tra nếu không thông báo cho tôi
iOS

Không hoạt động cho ios 9. Nó không có viền trên phần góc.
Jey

24

iOS 11, Swift 4
Và bạn có thể thử mã này:

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

Và bạn có thể sử dụng điều này trong ô xem bảng.


1
đó là câu trả lời đúng cho mã hóa ngày nay. tạm biệt lớp mặt nạ.
Alen Lương

1
Đây phải là câu trả lời tốt nhất!
fujianjin6471

18

Đây sẽ là câu trả lời đơn giản nhất:

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

thẻ đó là giải pháp cho iOS 11 trở lên
Ankur Lahiry

16

Hãy thử mã này,

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: .TopRight.BottomRightkhông làm việc cho bạn có lẽ vì cuộc gọi đến view.roundCornersđược thực hiện TRƯỚC cuối cùng view boundsđược tính toán. Lưu ý rằng các Bezier Pathxuất phát từ giới hạn xem tại thời điểm nó được gọi. Ví dụ: nếu bố trí tự động sẽ thu hẹp chế độ xem, các góc tròn ở phía bên phải có thể nằm ngoài chế độ xem. Hãy thử gọi nó trong đó viewDidLayoutSubviews, nơi giới hạn của khung nhìn là cuối cùng.


Cảm ơn bạn. Đối với tôi, điều đã giải quyết vấn đề là chuyển cuộc gọi sang triển khai được đưa ra bởi "Arbitur" từ viewDidLoad và viewWillAppear sang viewDidAppear. Tôi có thể làm như vậy vì điều khiển của tôi ban đầu được đặt thành ẩn.
Matti

Bạn đúng rồi. Nó sẽ tạo ra vấn đề với autolayout và bạn đã hoàn thành tốt công việc.
Ashish Kakkad

15

Swift 4 Swift 5 cách dễ dàng trong 1 dòng

Sử dụng:

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

Chức năng:

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

Trong Mục tiêu-C

Sử dụng:

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

Chức năng được sử dụng trong Danh mục (chỉ một góc):

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

Chỉ nhớ rằng các góc của chế độ xem của bạn không được tính cho đến khi viewDidLayoutSubview được thực hiện, do đó bạn nên gọi roundCorners func bên trong nó
Jirson Cheesa

Bạn có thể cho biết làm thế nào tôi có thể thêm bóng cho quan điểm này?
Vadlapalli Masthan

@ShakeelAhmed điều này sẽ không hoạt động nếu bạn muốn thêm bóng vào chế độ xem.
mojtaba al moussawi

đầu tiên thêm bán kính góc và sau đó thêm bóng
Shakeel Ahmed

10

Giải pháp của tôi để làm tròn các góc cụ thể của UIView và UITextFiels trong swift là sử dụng

.layer.c CornerRadius

layer.maskedCorners

của UIView hoặc UITextField thực tế.

Thí dụ:

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
    }

Và bằng cách sử dụng

.layerMaxXMaxYC Corner

.layerMaxXMinYC Corner

, Tôi có thể chỉ định góc trên cùng bên phải và dưới cùng bên phải của UITextField được làm tròn.

Bạn có thể xem kết quả ở đây:

nhập mô tả hình ảnh ở đây


Hoàn hảo cho kết hợp đường viền và góc cụ thể 🎉🎉🎉
nomnom

8

Swift 4

extension UIView {

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

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

Bạn đã lưu ngày của tôi trong trường hợp của tôi, tôi phải làm cho chế độ xem bảng được làm tròn cho các ô cụ thể
Shakti

Ans hoàn hảo theo yêu cầu của tôi. Tôi đã sử dụng tất cả các câu trả lời, không có gì làm việc cho tôi, nhưng câu trả lời của bạn đã giúp tôi và giải quyết vấn đề của tôi.
Nikita Patil

6

Một cách để làm điều này theo lập trình sẽ là tạo ra UIViewphần trên của phần UIViewcó các góc tròn. Hoặc bạn có thể ẩn đầu bên dưới một cái gì đó.


6
Đây là một giải pháp rất xấu xí: 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

Cách dễ nhất là làm mặt nạ với một lớp góc trò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;

Và đừng quên:

#import <QuartzCore/QuartzCore.h>

4

Tất cả các câu trả lời đã được đưa ra là thực sự tốt và hợp lệ (đặc biệt là ý tưởng của Yunus về việc sử dụng mask tài sản ).

Tuy nhiên tôi cần một cái gì đó phức tạp hơn một chút vì lớp của tôi thường có thể thay đổi kích thước, điều đó có nghĩa là tôi cần phải gọi logic mặt nạ đó mỗi lần và điều này hơi khó chịu.

Tôi đã sử dụng extensionscác thuộc tính nhanh chóng và tính toán để xây dựng một thực tếcornerRadii tự động cập nhật mặt nạ khi lớp được đặt ra.

Điều này đạt được bằng Peter Steinberg lớn khía cạnh thư viện để làm mờ.

Mã đầy đủ ở đây:

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

Tôi đã viết một bài đăng blog đơn giản giải thích điều này.



2

Đây là cách bạn có thể đặt bán kính góc cho mỗi góc của nút bằng Xamarin trong 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

Một phần mở rộng đáng yêu để tái sử dụng giải pháp 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
} }

Sử dụng

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

Giải pháp sạch đẹp
Kẻ xâm lược

1

Sau khi thay đổi bit mã @apinho Trong swift 4.3 hoạt động tốt

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

Để sử dụng chức năng này cho bạn xem

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

0

Một phiên bản khác của câu trả lời của Stephane .

import UIKit

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

    }

0

Trong Swift 4.2, Tạo nó thông qua @IBDesignablenhư thế này:

@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

Mở rộng đơn giản

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

Sử dụng:

view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.