Définir un rayon de coin de UIView
peut être effectué de la manière suivante:
Définissez la propriété layer
's cornerRadius
:
view.layer.cornerRadius = 5;
view.layer.masksToBounds = true;
Appliquez un masque:
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
}
Remplacer draw(_:)
:
func draw(_ rect: CGRect) {
// Size of rounded rectangle
let rectWidth = rect.width
let rectHeight = rect.height
// Find center of actual frame to set rectangle in middle
let xf: CGFloat = (self.frame.width - rectWidth) / 2
let yf: CGFloat = (self.frame.height - rectHeight) / 2
let ctx = UIGraphicsGetCurrentContext()!
ctx.saveGState()
let rect = CGRect(x: xf, y: yf, width: rectWidth, height: rectHeight)
let clipPath = UIBezierPath(roundedRect: rect, cornerRadius: rectCornerRadius).cgPath
ctx.addPath(clipPath)
ctx.setFillColor(rectBgColor.cgColor)
ctx.closePath()
ctx.fillPath()
ctx.restoreGState()
}
Lequel de ceux-ci est généralement considéré comme le "bon" moyen d'implémenter des angles arrondis sur un UIView
, en tenant compte des critères suivants:
cornerRadius
)Re vos trois options:
Utilisation de CALayer
propriétés existantes: il s'agit d'une solution facile (et probablement la plus efficace) pour le masquage de coin simple. C'est animable aussi. Dans iOS 11, vous pouvez choisir les coins masqués.
Concernant les masques CAShapeLayer
personnalisés: c’est une bonne approche si le masquage des coins n’est pas un simple arrondi mais des chemins arbitraires. Vous devez faire attention à mettre à jour ce masque si le frame
change (par exemple, dans layoutSubviews
NAME_ of view ou dans viewDidLayoutSubviews
NAME_ of controller). L'animation nécessite plus de travail.
Re custom draw(_:)
: Il s’agit de plus de travail que nécessaire et vous ne bénéficiez probablement pas des optimisations que l’équipe d’Apple a peut-être effectuées en arrière-plan (par exemple, si les appels draw
suivants ne dessinent qu’une partie du nom complet bounds
le code redessine le tout malgré tout).
Je suggérerais l'option 1 pour les cas simples et l'option 2 si vous avez besoin de plus de contrôle que l'option 1 ne peut en offrir. Mais il n'y a pas de "meilleure" approche: cela dépend de ce dont vous avez besoin et de la quantité de travail que vous êtes prêt à accomplir.
J'ai fait quelques tests avec iOS 11 ou une version antérieure et la meilleure pratique que j'ai découverte pour contourner un coin ou tous les coins, vous pouvez le faire avec le code suivant.
// Full size
CGSize vSize = [UIScreen mainScreen].bounds.size;
// Object
UIView *viewTest = [[UIView alloc] initWithFrame: CGRectMake(0, 0, vSize.width, vSize.height)];
[viewTest setAutoresizingMask: UIViewAutoresizingFlexibleHeight];
[viewTest setBackgroundColor: [UIColor grayColor]];
// maskedCorners is only available in iOS 11
if (@available(iOS 11.0, *)) {
[viewTest setClipsToBounds: YES];
[viewTest.layer setCornerRadius: 10];
// Only if you want to round the left and right top corners
[viewTest.layer setMaskedCorners: kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner];
}
else {
// The old way used in lower version
CAShapeLayer *cartCornersRound = [CAShapeLayer layer];
[cartCornersRound setPath: [UIBezierPath bezierPathWithRoundedRect: viewTest.bounds byRoundingCorners: UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii: (CGSize){10.0, 10.}].CGPath];
[viewTest.layer setMask: cartCornersRound];
}
La version Swift c'est quelque chose comme ça
let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 8
view.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner]
Je pense que ceci est le résumé le plus complet de tous: http://texturegroup.org/docs/corner-rounding.html
Mon heuristique est que si la vue n'a pas besoin de hautes performances (par exemple, ce n'est pas dans une cellule de vue de tableau), l'option la plus simple est d'utiliser la variable cornerRadius
de CALayer. Si vous avez besoin d'un rayon de coin plus avancé ou de performances élevées, il est préférable d'explorer d'autres options.