Coins arrondis uniquement au sumt d’une UIView

Salut, je cherche une solution propre sans écraser drawRect ou des choses comme ça pour créer un UIView avec des coins arrondis au sumt de la vue . Mon principal problème ici est de créer une solution variable si la vue est redimensionnée ou quelque chose comme ça. Y a-t-il une solution propre? Apple le fait aussi sur le premier élément de la table. ça ne peut pas être si difficile de faire ça.

Vous pouvez le faire en définissant un mask sur le calque de votre vue:

 CAShapeLayer * maskLayer = [CAShapeLayer layer]; maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: self.bounds byRoundingCorners: UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii: (CGSize){10.0, 10.}].CGPath; self.layer.mask = maskLayer; 

IMPORTANT: Vous devez le faire dans la méthode layoutSubviews() votre vue afin que la vue ait déjà été redimensionnée à partir du storyboard


En Swift <= 1.2

 let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: .TopLeft | .TopRight, cornerRadii: CGSize(width: 10.0, height: 10.0)).CGPath layer.mask = maskLayer 

Swift 2.x

 let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: bounds, byRoundingCorners: UIRectCorner.TopLeft.union(.TopRight), cornerRadii: CGSizeMake(10, 10)).CGPath layer.mask = maskLayer 

Swift 3.x

 let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 10, height: 10)).cgPath layer.mask = maskLayer 

Juste essayé avec Swift 3.0 , Xcode 8.0 :

viewDidLayoutSubviews() de définir votre bouton dans viewDidLayoutSubviews() ou layoutSubViews comme @rob décrit ici .

Et quand vous voulez changer l’arrière-plan de votre bouton, il vous suffit d’appeler:

 yourButton.backgroundColor = UIColor.someColour 

La source:

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() yourButton.layer.masksToBounds = true yourButton.roundCorners(corners: [.topLeft,.topRight], radius: 5) } extension UIButton { func roundCorners(corners:UIRectCorner, radius: CGFloat) { let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)).cgPath self.layer.mask = maskLayer } } 
  • Voici le résultat:

État par défaut:

entrer la description de l'image ici

État sélectionné:

entrer la description de l'image ici

J’espère que cette aide !!

J’ai travaillé avec l’aide de Ashley.

Tout d’abord, j’ai sous-classé un UIView. Créer un constructeur pour ma classe appelé - (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath; . Dans ce constructeur, je détermine quel type de cellule de table je veux styliser.

Ensuite, - (void)layoutSubviews l - (void)layoutSubviews pour créer CAShapeLayer et appliquer le masque de calque.

.h Code de fichier

 typedef enum { tableCellMiddle, tableCellTop, tableCellBottom, tableCellSingle } tableCellPositionValue; @interface TableCellBackgrounds : UIView { tableCellPositionValue position; } - (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath; @end 

.m Code de fichier

 - (id)initWithContentView:(UIView *)aView forTableView:(UITableView *)table andIndex:(NSIndexPath *)indexPath { self = [super initWithFrame:aView.frame]; [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; if(self) { [self setBackgroundColor:[UIColor colorWithRed:(float)230/255 green:(float)80/255 blue:(float)70/255 alpha:1]]; if(table.style == UITableViewStyleGrouped) { int rows = [table numberOfRowsInSection:indexPath.section]; if(indexPath.row == 0 && rows == 1) { self.layer.cornerRadius = 11; position = tableCellSingle; } else if (indexPath.row == 0) position = tableCellTop; else if (indexPath.row != rows - 1) position = tableCellMiddle; else position = tableCellBottom; } } return self; } - (void)layoutSubviews { [super layoutSubviews]; if(position == tableCellTop) { CAShapeLayer *maskLayer = [CAShapeLayer layer]; maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:(CGSize){10.0, 10.0}].CGPath; self.layer.mask = maskLayer; } else if (position == tableCellBottom) { CAShapeLayer *maskLayer = [CAShapeLayer layer]; maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:(CGSize){10.0, 10.0}].CGPath; self.layer.mask = maskLayer; } } 

Avec swift 3.0, le dessous a fonctionné pour moi

 let maskLayer = CAShapeLayer() maskLayer.path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 10, height: 10)).cgPath (imageView.)layer.mask = maskLayer 

Important: assurez-vous qu’il se trouve dans «layoutSubviews», pas «awakeFromNib» (si vous utilisez un object TableViewCell) ou similaire pour UIView, ou seul le coin supérieur gauche est arrondi!

Une extension pour UIView qui arrondit les coins sélectionnés (Swift 4):

 extension UIView { /// Round UIView selected corners /// /// - Parameters: /// - corners: selected corners to round /// - radius: round amount 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 } } 

Exemple:

 ratingView.roundCorners([.topLeft, .topRight, .bottomRight], radius: 6) 
  CAShapeLayer * maskLayer = [CAShapeLayer layer]; maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: registerbtn.bounds byRoundingCorners: UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii: (CGSize){9.0, 12.0}].CGPath; registerbtn.layer.mask = maskLayer; 

cela ne fera qu’un coin arrondi

Le moyen le plus simple de le faire serait de définir un chemin dans la forme souhaitée et de le remplir avec la couleur que vous souhaitez utiliser pour l’arrière-plan. Vous pouvez utiliser soit UIBezierPath ou CGPath pour cela. En utilisant CGPath , par exemple, vous pouvez construire un chemin en utilisant des méthodes telles que CGMoveToPoint() , CGAddLineToPoint() et CGAddArc() . Vous devez ensuite le remplir avec CGContextFillPath() . Jetez un coup d’œil au Guide de programmation 2D de Quartz pour une discussion complète.

Une autre façon serait d’append une sous-vue avec des coins arrondis (vous pouvez définir la propriété cornerRadius de la couche de la sous-vue), mais laissez un côté de la sous-vue être coupé par la vue parente.

Une troisième façon serait d’append une image d’arrière-plan avec la forme souhaitée. Vous pouvez rendre les coins transparents et rendre l’arrière-plan de la vue transparent, et vous obtiendrez l’effet souhaité. Cela ne fonctionnera pas si bien pour le redimensionnement, cependant.

Où êtes-vous coincé?