Como definir o cornerRadius apenas para o canto superior esquerdo e superior direito de um UIView?


408

Existe uma maneira de definir cornerRadiusapenas o canto superior esquerdo e superior direito de um UIView?

Eu tentei o seguinte, mas ele acabou não vendo mais a vista.

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
Após sua edição, três coisas a serem corrigidas: (1) o caminho arredondado deve ser baseado view.bounds, não frame, (2) a camada deve ser a CAShapeLayer, não CALayer; (3) defina a camada path, não shadowPath.
— Kurt Revis

11
Possível duplicata desta pergunta e resposta .
— Stuart

Use o algoritmo de curva de Bezier, para criar curvas em um CGPath. Tenho certeza de que faz parte do CoreGraphics. Caso contrário, o site en.wikipedia.org/wiki/Bézier_curve possui ótimas definições e animações.
— Nate Symer # 01


Veja minha resposta aqui: stackoverflow.com/a/50396485/6246128
— wcarhart

Respostas:


226

Preste atenção ao fato de que, se você tiver restrições de layout associadas, atualize-o da seguinte forma na subclasse UIView:

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

Se você não fizer isso, não aparecerá.


E para os cantos arredondados, use a extensão:

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


Caso adicional do controlador de vista : Se você não pode ou não deseja subclassificar uma vista, ainda pode arredondá-la. Faça isso a partir do seu controlador de exibição, substituindo a viewWillLayoutSubviews()função, da seguinte maneira:

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
Não é absolutamente uma resposta, o autor estava perguntando como arredondar cantos específicos, não como sincronizar o raio dos cantos com as alterações de layout.
— #

11
Esta é a resposta não faz sentido.
— Tiago Couto

11
a resposta foi corrigida recentemente .. @kelin #
— Michael

2
isso definitivamente virou a esquina.
— precisa saber é o seguinte

Você precisa fazer isso depois que a vista aparecer
— Jonathan.

535

Não sei por que sua solução não funcionou, mas o código a seguir está funcionando para mim. Crie uma máscara de bezier e aplique-a à sua visualização. No meu código abaixo, eu estava arredondando os cantos inferiores do _backgroundViewcom um raio de 3 pixels. selfé um costume 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;

Versão Swift com algumas melhorias:

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

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

Versão 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

Extensão rápida aqui


2
tente no campo de texto. sucesso na esquerda, falha na direita
— Rainer Liao

10
@RainerLiao eu tive o mesmo problema, fiz tudo isso no viewDidLoadmétodo, movi- lo para viewDidAppeare funcionou.
— Lucho

como posso definir isso para funcionar em qualquer dispositivo. isso só funciona bem para o simulatortamanho do storyboard. ex: if the simulator size is 6s it works fine for 6s, but not of others.como posso superar isso.
— Chanaka Caldera

11
Pequeno erro de sintaxe na versão Swift 3: path.CGPathdeveria serpath.cgPath
— Rob

@RainerLiao se você não quiser que ele apareça conforme a visualização aparece, altere-a para viewWillAppear. Isso também funciona.
— Matthew knippen

263

Aqui está uma versão Swift da resposta @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)

Nota

Se você estiver usando o Layout automático , precisará subclassificar UIViewe chamar roundCornersa visualização layoutSubviewspara obter o efeito ideal.

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

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

12
Ótima extensão. No entanto: .TopRighte .BottomRightnão parece funcionar para mim.
— Onichan 25/03

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

2
Não está funcionando do lado direito, porque os limites de sua visualização ainda não estão bem definidos com o layout automático ... Atualmente, estou enfrentando o mesmo problema.
— dosdos

3
@dosdos Subclasse que visualiza e no layoutSubviews arredondam os cantos de si.
— Arbitur #

10
Se você usa o layout automático e não tem a referência para a exibição que deseja arredondar, pode chamar .layoutIfNeeded()esse método.
— Zgjie 18/05

210

E finalmente… existe o CACornerMask no iOS11! Com CACornerMaskisso pode ser feito muito fácil:

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

11
isso definitivamente funciona melhor. sempre tivemos problemas com as outras soluções ao arredondar as bordas das células de tableview com dimensionamento dinâmico.
— cornr

2
O projeto deve oferecer suporte ao iOS 11 em diante para usar essa solução.
— Aliens

13
@ Aliens e ... eu mencionei isso.
— Sergey Belous

11
As outras respostas não funcionam ao girar o dispositivo, esse código funciona para rotação e permite que você rode algumas esquinas; essa deve ser a resposta aceita.
— precisa saber é o seguinte

11
Simples é bonito #
— eharo2

99

Exemplo de código Swift aqui: https://stackoverflow.com/a/35621736/308315


Não diretamente. Voce terá que:

  1. Crie um CAShapeLayer
  2. Defina pathcomo CGPathRefbaseado, view.boundsmas com apenas dois cantos arredondados (provavelmente usando +[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:])
  3. Defina seu view.layer.maskpara ser oCAShapeLayer

21
Esteja avisado isso vai prejudicar o desempenho se você fazê-lo em mais do que apenas um par de pontos de vista ...
— jjxtra

@jjxtra Então, qual é a melhor maneira de fazer isso sem muita perda de desempenho? Eu quero mostrá-lo em UITableViewCell.
— Xi.lin

@ xi.lin pelo que me lembro de definir layer.shouldRasterize == SIM melhora a velocidade 5 vezes mais ou menos. Mas os documentos dizem que só funciona se você trabalhar com células não transparentes. Experimente.
— Codrut # 9/17

64

Aqui está um método curto implementado assim:

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

Que tal definir cores? maskLayer.borderWidth = 10; maskLayer.borderColor = [UIColor redColor] .CGColor; não está funcionando para mim, senhor.
— kiran

11
@kiran uma máscara não tem uma cor, você pode adicionar uma segunda CAShapeLayer se você quiser ter uma borda
— Johnny Rockex

25

No Swift 4.1 e no Xcode 9.4.1

No iOS 11, essa única linha é suficiente:

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

Veja o código completo:

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

Mas para versões inferiores

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

O código completo é.

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
}

Se você estiver usando o AutoResizing no storyboard, escreva este código em 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
    }
}

11
Não é o trabalho iOS 9, mas funciona com o 11
— Ali Ihsan URAL

Alguma solução para o ios 9?
— jey

@jay deixe rectShape = CAShapeLayer () rectShape.bounds = detailsSubView.frame rectShape.position = detailsSubView.center rectShape.path = UIBezierPath (roundedRect: detailsSubView.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: cornerRadii 20, height: 20)). CgPath detailsSubView.layer.mask = rectShape Este código pode funcionar no iOS 9
— iOS

@ jay verificar se não me informar
— iOS

Não está funcionando para o ios 9. Não há borda na parte do canto.
— jey

24

iOS 11, Swift 4
E você pode tentar este código:

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

E você pode usar isso na célula de exibição de tabela.


11
essa é a resposta certa para a codificação de hoje. adeus para mascarar a camada.
— Alen Liang

11
Essa deve ser a melhor resposta!
— fujianjin6471 3/06/19

18

Esta seria a resposta mais simples:

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

tag que é a solução para iOS 11 ou superior
— Ankur Lahiry

16

Experimente este código,

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: .TopRighte .BottomRightnão está trabalhando para você, talvez porque a chamada para view.roundCornersé feita ANTES da final view boundsser calculada. Observe que o valor Bezier Pathderiva dos limites da vista no momento em que é chamada. Por exemplo, se o layout automático restringir a vista, os cantos arredondados no lado direito podem estar fora da vista. Tente ligar viewDidLayoutSubviews, onde o limite da visualização é final.


Obrigado. Para mim, o que resolveu o problema foi mover a chamada para a implementação fornecida pelo "Arbitur" de viewDidLoad e viewWillAppear para viewDidAppear. Eu poderia fazer isso, pois meu controle é inicialmente definido como oculto.
— Matti

Você está certo. Isso criará problemas com o pagamento automático e você fez um bom trabalho.
— Ashish Kakkad

15

Swift 4 Swift 5 maneira fácil em 1 linha

Uso:

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

Função:

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

No Objetivo-C

Uso:

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

Função usada em uma categoria (apenas um canto):

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

Apenas lembre-se que os cantos de sua visão não são calculados até o viewDidLayoutSubviews é feito para que você deve chamar roundCorners func dentro dele
— Jirson Tavera

você pode dizer como posso adicionar sombra a essas visualizações?
— Vadlapalli Masthan

@ ShakeelAhmed, isso não funcionará se você quiser adicionar uma sombra à exibição.
— Mojtaba al moussawi 02/07/19

primeiro raio de canto add e depois adicionar sombra
— Shakeel Ahmed

10

Minha solução para arredondar cantos específicos do UIView e UITextFiels no swift é usar

.layer.cornerRadius

e

layer.maskedCorners

de UIView ou UITextFields reais.

Exemplo:

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
    }

E usando

.layerMaxXMaxYCorner

e

.layerMaxXMinYCorner

, Posso especificar o canto superior direito e inferior direito do UITextField a ser arredondado.

Você pode ver o resultado aqui:

insira a descrição da imagem aqui


Perfeito para combinação de bordas e cantos específicos 🎉🎉🎉
— nomnom 22/01

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

Você salvou meu dia no meu caso eu tive que fazer a exibição de tabela arredondado para células particulares
— Shakti

Ans perfeito de acordo com minha exigência. Eu usei toda a resposta, nada funcionou para mim, mas sua resposta me ajudou e resolveu meu problema.
— Nikita Patil

6

Uma maneira de fazer isso programaticamente seria criar uma UIViewparte superior da parte UIViewque possui cantos arredondados. Ou você pode esconder o topo por baixo de alguma coisa.


6
É uma solução muito feia: 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

A maneira mais fácil seria fazer uma máscara com uma camada de canto arredondado.

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

aUIView.layer.mask = maskLayer;

E não se esqueça de:

#import <QuartzCore/QuartzCore.h>

4

Todas as respostas já dadas são realmente boas e válidas (especialmente a idéia de Yunus de usar a maskpropriedade).

No entanto, eu precisava de algo um pouco mais complexo, porque minha camada costumava mudar de tamanho, o que significa que eu precisava chamar essa lógica de mascaramento todas as vezes e isso era um pouco chato.

Usei extensionspropriedades rápidas e computadas para criar uma cornerRadiipropriedade real que cuida da atualização automática da máscara quando a camada é colocada.

Isto foi conseguido usando a grande biblioteca de Aspectos Peter Steinberg para swizzling.

O código completo está aqui:

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

Eu escrevi um post simples explicando isso.



2

É assim que você pode definir um raio de canto para cada canto de um botão com o Xamarin em 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

Uma extensão adorável para reutilizar a solução 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
} }

Uso

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

Solução limpa e agradável
— Aggressor

1

Depois da alteração do código @apinho No Swift 4.3 funcionando bem

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

Para usar esta função para você visualizar

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

0

Outra versão da resposta de 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

No Swift 4.2, crie-o @IBDesignableassim:

@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

Extensão simples

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

Uso:

view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.