139 votes

Comment dessiner une UIView personnalisée qui n'est qu'un cercle - application iPhone

Comment puis-je dessiner un UIView personnalisé qui n'est littéralement qu'une boule (un cercle en 2D) ? Est-ce que je dois simplement surcharger la méthode drawRect ? Et quelqu'un peut-il me montrer le code pour dessiner un cercle bleu ?

De même, serait-il possible de modifier le cadre de cette vue dans la classe elle-même ? Ou dois-je modifier le cadre à partir d'une autre classe ?

(j'essaie juste de mettre en place une balle qui rebondit)

217voto

Kal Points 14230

Vous pourriez utiliser QuartzCore et faire quelque chose comme ceci --

self.circleView = [[UIView alloc] initWithFrame:CGRectMake(10,20,100,100)];
self.circleView.alpha = 0.5;
self.circleView.layer.cornerRadius = 50;  // half the width/height
self.circleView.backgroundColor = [UIColor blueColor];

105 votes

Pour votre information, pour que votre vue soit un cercle avec QuartCore, le rayon de vos coins doit être égal à la moitié de la hauteur/largeur de votre cadre. C'est la façon la plus simple de faire un cercle, mais ce n'est pas nécessairement la plus efficace. Si les performances sont vitales, drawRect donnera probablement de meilleurs résultats.

4 votes

Et c'est le cas. 100 est la hauteur/largeur.

3 votes

Oui, désolé, ce n'était pas dirigé contre toi, Kal. Je le disais à StanLe au cas où il voudrait utiliser des vues de tailles différentes.

137voto

Steve Points 18193

Est-ce que je dois simplement surcharger la méthode drawRect ?

Oui :

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddEllipseInRect(ctx, rect);
    CGContextSetFillColor(ctx, CGColorGetComponents([[UIColor blueColor] CGColor]));
    CGContextFillPath(ctx);
}

De même, serait-il possible de modifier le cadre de cette vue dans la classe elle-même ?

Idéalement non, mais vous pourriez.

Ou dois-je changer le cadre d'une autre classe ?

Je laisserais les parents contrôler ça.

1 votes

Comment puis-je définir des couleurs personnalisées, pas seulement le bleu ? J'essaie d'utiliser le blanc et le bleu comme ceci : ([self.colorOfCircle CGColor]) mais rien ne se passe :-)

0 votes

@loldop self.colorOfCircle est-il un UIColor ? Est-il défini ? Si vous mettez un point d'arrêt sur cette ligne et regardez la valeur, est-ce que c'est ce que vous attendez ? Si vous la définissez après coup, vous devrez invalider la partie de votre vue qui contient le cercle.

10 votes

@gaussblurinc utilise CGContextSetFillColorWithColor(ctx, self.colorOfCircle.CGColor); la méthode proposée dans la solution CGColorGetComponents ne fonctionne qu'avec certaines couleurs, voir stackoverflow.com/questions/9238743/

31voto

Gintama Points 85

Voici une autre façon d'utiliser UIBezierPath (c'est peut-être trop tard ^^) Créer un cercle et masquer UIView avec, comme suit :

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
view.backgroundColor = [UIColor blueColor];

CAShapeLayer *shape = [CAShapeLayer layer];
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:view.center radius:(view.bounds.size.width / 2) startAngle:0 endAngle:(2 * M_PI) clockwise:YES];
shape.path = path.CGPath;
view.layer.mask = shape;

1 votes

Il n'est pas vraiment nécessaire de faire de ce calque de forme un masque ; vous pouvez simplement utiliser le calque de forme directement comme calque de la vue et lui donner une couleur de remplissage. Le masque est probablement beaucoup plus coûteux.

0 votes

Le calque de UIView est CALayer donc comment pouvons-nous dessiner une forme sur ce calque. Je suppose que nous ajoutons le calque de la forme au calque de la vue sans le masquer ?

1 votes

Vous pouvez sous-classer UIView et surcharger la fonction layerClass pour en faire une couche de forme.

29voto

Kevin ABRIOUX Points 6237

Ma contribution avec une extension Swift :

extension UIView {
    func asCircle() {
        self.layer.cornerRadius = self.frame.width / 2;
        self.layer.masksToBounds = true
    }
}

Appelez simplement myView.asCircle()

0 votes

Paramètre masksToBounds à true et en utilisant self sont toutes optionnelles dans cette réponse, mais c'est toujours la solution la plus courte et la meilleure.

22voto

MobiMaciek Points 1767

Swift 3 - classe personnalisée, facile à réutiliser. Elle utilise backgroundColor défini dans le constructeur d'interface utilisateur

import UIKit

@IBDesignable
class CircleBackgroundView: UIView {

    override func layoutSubviews() {
        super.layoutSubviews()
        layer.cornerRadius = bounds.size.width / 2
        layer.masksToBounds = true
    }

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X