web-dev-qa-db-fra.com

drawRect n'est pas appelé dans ma sous-classe de UIImageView

J'ai sous-classé UIImageView et j'ai essayé de remplacer drawRect afin de pouvoir dessiner par-dessus l'image en utilisant Quartz 2D. Je sais que c'est une question stupide pour un débutant, mais je ne vois pas ce que j'ai fait de mal. Voici l'interface:

#import <UIKit/UIKit.h>

@interface UIImageViewCustom : UIImageView {

}
- (void)drawRect:(CGRect)rect;
@end

Et la mise en place:

#import "UIImageViewCustom.h"

@implementation UIImageViewCustom

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    // do stuff
}

- (void)dealloc {
    [super dealloc];
}
@end

J'ai défini un point d'arrêt sur drawRect et il ne frappe jamais, ce qui me porte à penser qu'il n'est jamais appelé. N'est-il pas censé être appelé lors du premier chargement de la vue? Est-ce que j'ai mal remplacé?

39
Ben Collins

Il ne sera appelé que si la vue est visible et sale. Peut-être que le problème provient du code qui crée la vue ou de votre Nib, si c'est comme ça que vous le créez?

Vous verrez également parfois que les points d'arrêt ne sont pas correctement définis si vous essayez de déboguer une version "Release".


J'ai en quelque sorte manqué la première fois que vous sous-classez UIImageView. De la docs:

Considérations particulières

La classe UIImageView est optimisée pour dessine ses images sur l'écran . UIImageView n'appellera pas drawRect: dans un sous-classe. Si votre sous-classe a besoin de code de dessin personnalisé, il est recommandé vous utilisez UIView comme classe de base.

Donc là vous l'avez. Étant donné la facilité avec laquelle il est possible de dessiner une image dans votre vue avec [UIImage drawInRect:] ou avec CALayer, il n’ya probablement aucune bonne raison de sous-classer UIImageView.

84
Mark Bessey

Essayez d'ajouter

Modifier:

- (id)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        [self setClearsContextBeforeDrawing:YES];//add this line also
    }
    return self;
}


- (void)setNeedsDisplay{
    [self setNeedsDisplayInRect:self.frame];
}

dans votre code. 

j'espère que cela t'aides. 

Thanos,

écraser

1
Madhup Singh Yadav

Selon votre cas, il peut être judicieux d’utiliser une UIButton avec une image d’arrière-plan au lieu d’une UIImageView. Vous pouvez même définir userInteractionEnabled sur NO et le résultat ne pourrait pas être distingué d'un UIImageView.

Dans ce cas, votre sous-classe UIButton comprendrait simplement:

- (void)drawRect:(CGRect)rect
{
  if (kSomethingSpecial) {
    [self setBackgroundImage:[UIImage imageNamed:@"RedBackground.png"] 
                    forState:UIControlStateNormal];
  }
}

Déni de responsabilité - Je ne le recommanderais que si vous envisagez d'utiliser l'image au moins une partie du temps comme bouton. Je ne peux absolument pas recommander l'utilisation de UIButton comme solution de contournement pour ce comportement drawRect dans UIImageView, car je suis sûr que Apple a les raisons pour lesquelles son API est écrite de cette manière, comme Mark en référence.

0
Kyle Clegg

Ne répondez pas directement à votre question, mais pourrait résoudre votre problème:

Pourquoi faire cela avec une sous-classe de UIImageView? Le sous-classement peut toujours être problématique, en particulier pour les classes qui ne sont pas conçues pour le faire - et je parie que UIImageView ne l’est pas. Si vous souhaitez simplement dessiner des éléments par-dessus une image, créez une vue avec un arrière-plan transparent, dessinez ce que vous voulez et placez-la directement sur l'image.

0
jasoncrawford