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 } }
État par défaut:
État sélectionné:
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é?