Как установить cornerRadius только для верхнего левого и верхнего правого угла UIView?

408

Есть ли способ установить cornerRadius только верхний левый и верхний правый угол UIView?

Я попробовал следующее, но в итоге я больше не видел вид.

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
После редактирования нужно исправить три вещи: (1) округленный путь должен основываться view.bounds, а не frame(2) слой должен быть, а CAShapeLayerне CALayer; (3) установить слой path, а не shadowPath.
Курт Ревис
1
Возможный дубликат этого вопроса и ответа .
Стюарт
Используйте алгоритм кривой Безье, чтобы создать кривые на CGPath. Я уверен, что это часть CoreGraphics. Если нет, en.wikipedia.org/wiki/Bézier_curve имеет несколько отличных определений и анимаций.
Нейт Симер
Смотрите мой ответ здесь: stackoverflow.com/a/50396485/6246128
wcarhart

Ответы:

226

Обратите внимание на тот факт, что если у вас есть ограничения макета, вы должны обновить это следующим образом в своем подклассе UIView:

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

Если вы этого не сделаете, он не появится.


А для закругления углов используйте расширение:

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


Дополнительный случай контроллера представления : Если вы не можете или не хотите создавать подклассы представления, вы все равно можете округлить представление. Сделайте это из контроллера своего представления, переопределив viewWillLayoutSubviews()функцию следующим образом:

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)
    }
}
Стефан де Лука
источник
3
Это абсолютно не ответ, автор спрашивал, как закруглить отдельные углы, а не как синхронизировать радиус угла с изменениями макета.
Келин
1
Это ответ не имеет смысла.
Tiago Couto
1
ответ был исправлен недавно .. @kelin
Майкл
2
это определенно закруглило угол.
aznelite89
Вы должны сделать это после того, как представление появилось
Джонатан.
535

Я не уверен, почему ваше решение не сработало, но следующий код работает для меня. Создайте маску Безье и примените ее к своему виду. В моем коде ниже я округлял нижние углы _backgroundViewс радиусом 3 пикселя. selfэто обычай 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;

Swift версия с некоторыми улучшениями:

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:

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

Быстрое расширение здесь

Юнус Недим Мехел
источник
2
попробуйте в текстовом поле. успех слева, провал справа
Райнер Ляо
10
@RainerLiao У меня была такая же проблема, я сделал все это с viewDidLoadметодом, переместил его viewDidAppearи он заработал.
Лучо
Как я могу настроить это для работы на любом устройстве. это работает только для simulatorразмера int раскадровки. ex: if the simulator size is 6s it works fine for 6s, but not of others.как я могу преодолеть это.
Кальдера
1
Маленькая синтаксическая ошибка в версии Swift 3: path.CGPathдолжно бытьpath.cgPath
Роб
@RainerLiao, если вы не хотите, чтобы он мигал при отображении вида, измените его на viewWillAppear. Это тоже работает.
Мэтью Книппен
263

Вот Swift- версия ответа @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)

Запись

Если вы используете автоматическую компоновку , вам нужно будет создать подкласс своего UIViewи вызвать roundCornersпредставления layoutSubviewsдля оптимального эффекта.

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

        self.roundCorners([.topLeft, .bottomLeft], radius: 10)
    }
}
Arbitur
источник
12
Отличное продолжение. Однако: .TopRightи .BottomRight, похоже, не работает для меня.
Оничан
4
на Свифте 2 :view.roundCorners([.TopLeft , .BottomLeft], radius: 10)
Фахрулазми
2
Это не работает справа, потому что границы вашего представления еще не определены с помощью autolayout ... В настоящее время я сталкиваюсь с той же проблемой.
Досдос
3
@dosdos Подкласс этого вида и в layoutSubviews по углам самого себя.
Арбитур
10
Если вы используете автоматическую разметку и не хотите округлить ссылку на представление, вы можете вызвать .layoutIfNeeded()этот метод.
zgjie
210

И , наконец , ... есть CACornerMask в iOS11! С CACornerMaskэтим можно сделать довольно легко:

let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 10
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Top right corner, Top left corner respectively
Сергей Белоус
источник
1
это определенно работает лучше всего. у нас всегда были проблемы с другими решениями при округлении границ динамически изменяемых размеров ячеек таблицы.
Cornr
2
Проект должен поддерживать iOS 11 и выше, чтобы использовать это решение.
Иностранцы
13
@Aliens и ... я упоминал об этом.
Сергей Белоус
1
Другие ответы не работают при вращении устройства, этот код работает для вращения и позволяет вам закруглять определенные углы, это должен быть принятый ответ.
Cloud9999Strife
1
Просто красиво
eharo2
99

Пример кода Swift здесь: https://stackoverflow.com/a/35621736/308315


Не напрямую. Тебе придется:

  1. Создать CAShapeLayer
  2. Установите его pathна CGPathRefоснове, view.boundsно только с двумя закругленными углами (возможно, используя +[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:])
  3. Установите, view.layer.maskчтобы бытьCAShapeLayer
Курт Ревис
источник
21
Имейте в
виду, что это ухудшит
@jjxtra Итак, как лучше всего это сделать без особых потерь производительности? Я хочу показать это в UITableViewCell.
xi.lin
@ xi.lin, насколько я помню, установка layer.shouldRasterize == ДА повышает скорость примерно в 5 раз. Но документы говорят, что это работает, только если вы работаете с непрозрачными ячейками. Дать ему шанс.
codrut
64

Вот краткий метод, реализованный следующим образом:

- (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;
}
Джонни Рокекс
источник
Как насчет настройки цвета? maskLayer.borderWidth = 10; maskLayer.borderColor = [UIColor redColor] .CGColor; это не работает для меня, сэр.
Киран
1
@kiran маска не имеет цвета, вы можете добавить второй CAShapeLayer, если хотите иметь рамку
Johnny Rockex
25

В swift 4.1 и Xcode 9.4.1

В iOS 11 достаточно одной строки:

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

Смотрите полный код:

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

Но для более низких версий

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

Полный код есть.

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
}

Если вы используете AutoResizing в раскадровке, напишите этот код в 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
источник
1
Это не работает iOS 9, но работает на 11
Али Ихсан URAL
Любое решение для ios 9?
джей
@jay let rectShape = CAShapeLayer () rectShape.bounds = detailsSubView.frame rectShape.position = detailsSubView.center rectShape.path = UIBezierPath (округленныйRect: detailsSubView.bounds, byRoundingCorners: [.topLeft, .topRight C: 20, высота: 20)). CgPath detailsSubView.layer.mask = rectShape Этот код может работать для iOS 9
iOS
@ Джей проверить, если не сообщите мне
iOS
Не работает для ios 9. Его нет границы на угловой части.
Джей
24

iOS 11, Swift 4
И вы можете попробовать этот код:

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

И вы можете использовать это в ячейке табличного представления.

reza_khalafi
источник
1
это правильный ответ для сегодняшнего кодирования. пока, пока, чтобы замаскировать слой.
Ален Лян
1
Это должно быть лучшим ответом!
fujianjin6471
18

Это был бы самый простой ответ:

yourView.layer.cornerRadius = 8
yourView.layer.masksToBounds = true
yourView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
pierre23
источник
отметьте, что это решение для iOS 11 или выше
Ankur Lahiry
16

Попробуйте этот код,

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

Эмма: .TopRightи .BottomRightне работаем для вас, возможно, потому что вызов view.roundCornersсделан до финального view boundsрасчета. Обратите внимание, что Bezier Pathпроизводные от границ представления во время его вызова. Например, если автоматическое расположение сузит вид, закругленные углы с правой стороны могут быть за пределами вида. Попробуйте позвонить туда viewDidLayoutSubviews, где граница представления является окончательной.

Дэвид Барта
источник
Спасибо. Для меня то, что решило проблему, было перемещение вызова к реализации, данной "Arbitur" от viewDidLoad и viewWillAppear к viewDidAppear. Я мог бы сделать это, так как мой контроль изначально установлен как скрытый.
Матти
Вы правы. Это создаст проблему с autolayout, и вы хорошо поработали.
Ашиш Каккад
15

Swift 4 Swift 5 простой способ в 1 линию

Применение:

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

Функция:

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

В Objective-C

Применение:

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

Функция, используемая в категории (только один угол):

-(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;
    }
Шакил Ахмед
источник
Только помните, что углы вашего представления не рассчитываются до тех пор, пока viewDidLayoutSubviews не будет завершен, поэтому вы должны вызвать внутри него
функцию roundCorners
Можете ли вы сказать, как я могу добавить тень к этим представлениям?
Вадлапалли Мастан
@ShakeelAhmed это не будет работать, если вы хотите добавить тень к виду.
Мойтаба аль Мусави
сначала добавьте угловой радиус, а затем добавьте тень
Shakeel Ahmed
10

Мое решение для округления определенных углов UIView и UITextFiels в swift заключается в использовании

.layer.cornerRadius

а также

layer.maskedCorners

фактического UIView или UITextFields.

Пример:

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
    }

И с помощью

.layerMaxXMaxYCorner

а также

.layerMaxXMinYCorner

Я могу указать верхний правый и нижний правый угол UITextField для округления.

Вы можете увидеть результат здесь:

введите описание изображения здесь

Бэйн М
источник
Идеально подходит для комбинации бордюров и определенных углов 🎉🎉🎉
номном
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
источник
Вы спасли мой день, в моем случае мне пришлось сделать округление таблицы для отдельных ячеек
Shakti
Идеальный ответ по моему требованию. Я использовал все ответы, у меня ничего не получалось, но ваш ответ помог мне и решил мою проблему.
Никита Патил
6

Способ сделать это программно - создать UIViewверхнюю часть UIViewс закругленными углами. Или вы могли бы спрятать верхнюю часть под чем-то.

Нейт Симер
источник
6
Это очень уродливое решение: P
Arbitur 12.12.14
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
источник
4

Самый простой способ - сделать маску с закругленным угловым слоем.

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

aUIView.layer.mask = maskLayer;

И не забудьте:

#import <QuartzCore/QuartzCore.h>
Мэтт Хадсон
источник
4

Все ответы, которые уже даны, являются действительно хорошими и действительными (особенно идея Юнуса об использовании maskсобственности).

Однако мне нужно было что-то немного более сложное, потому что мой слой часто менял размеры, что означало, что мне нужно каждый раз вызывать эту логику маскирования, и это немного раздражало.

Я использовал быстрые extensionsи вычисленные свойства, чтобы создать реальное cornerRadiiсвойство, которое позаботится об автоматическом обновлении маски при разметке слоя.

Это было достигнуто с помощью Peter Стейнберга больших аспектов библиотеки для swizzling.

Полный код здесь:

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

Я написал простой пост в блоге, объясняющий это.

apouche
источник
3

Если вы ищете решение только для конструктора интерфейсов, есть одно для iOS 11 и выше . Смотрите мой ответ здесь: https://stackoverflow.com/a/58626264

Бруно Биери
источник
2

Вот как вы можете установить радиус угла для каждого угла кнопки с Xamarin в 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
источник
2

Прекрасное продолжение для повторного использования решения 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
} }

Применение

let view = UIView()
view.roundCornersWithLayerMask(10,[.TopLeft,.TopRight])
apinho
источник
Хорошее чистое решение
Aggressor
1

После изменения немного кода @apinho В Swift 4.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
  }
}

Чтобы использовать эту функцию для просмотра

YourViewName. roundCornersWithLayerMask(cornerRadii: 20,corners: [.topLeft,.topRight])
Санджай Мишра
источник
0

Еще одна версия ответа Стефана .

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

В Swift 4.2 создайте его @IBDesignableследующим образом:

@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

Простое расширение

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

Применение:

view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
FunkyKat
источник