2010-10-10 27 views
7

Je suis en train de dessiner une image de fond répétitif dans mon NSView, j'ai ce jusqu'à maintenant:Cyclique image de fond dans un NSView

// INIT 
- (id)initWithFrame:(NSRect)frame { 
    if (self = [super initWithFrame:frame]) { 
    self.backgroundImage = [NSImage imageNamed:@"progressBackground.pdf"]; 
    } 

    return self; 
} 

// DRAW 
- (void)drawRect:(NSRect)dirtyRect { 
    // Draw the background 
    [backgroundImage drawInRect:[self bounds] 
        fromRect:NSMakeRect(0.0f, 0.0f, backgroundImage.size.width, backgroundImage.size.height) 
        operation:NSCompositeSourceAtop 
        fraction:1.0f]; 
    NSLog(@"%dx%d", backgroundImage.size.width, backgroundImage.size.height); 
} 

Cependant, la vue s'étend l'image à se remplir. Je veux que l'image répète à la place.

alt text (les traits noirs sont fixés déjà)

En outre, quelque chose d'étrange se produit, comme la console dit la taille de l'image est égale à -2109897792x0, mais l'image est vraiment 32x32! WTF ?!

Quelqu'un pourrait-il me aider, s'il vous plaît? Merci.

+2

Probablement pas la meilleure idée pour menacer de voter en aval pour des réponses sans rapport que vous * pourriez * recevoir. Cela a tendance à décourager les gens de s'inquiéter du tout. –

+2

@Joshua mais il est très, très ennuyeux de recevoir des réponses sur la mauvaise plate-forme. –

+0

Vous voyez certainement la différence entre admonester des gens avant que quelqu'un ne fasse quelque chose de mal et le faire à la suite d'une infraction réelle. Le premier est hostile au mieux; ce dernier est plus méritant. –

Répondre

20

Vous pouvez créer une couleur de motif avec +[NSColor colorWithPatternImage:], puis remplir simplement le rectangle d'arrière-plan avec cette "couleur". Cela devrait faire ce que vous voulez accomplir.

+0

Cool! Ça marche. = D –

+2

Sachez que c'est relatif au bas de la fenêtre (par les docs). Au fur et à mesure que vous redimensionnez la fenêtre (et que la vue se redimensionne en réponse), le point supérieur gauche du motif bouge (l'arrière-plan «nage» derrière les sous-vues de votre vue à motifs). Cela peut être nauséeux. :-) –

+3

Je sais que cet article est assez vieux, mais j'ai ce problème exact. est-il possible de faire le dock "backgroundimage" vers le haut? –

15

J'ai trouvé la réponse ici pour éviter des motifs de tirer du fond et de donner cet effet bizarre lorsque les fenêtres se redimensionnent:

http://www.mere-mortal-software.com/blog/details.php?d=2007-01-08

Fondamentalement, tout ce que vous devez faire dans votre drawRect est d'enregistrer votre contexte graphique état, appelez la méthode, peignez votre motif, puis rétablissez votre état.

La méthode est:

- (void)drawRect:(NSRect)dirtyRect { 
    NSGraphicsContext* theContext = [NSGraphicsContext currentContext]; 
    [theContext saveGraphicsState]; 
    [[NSGraphicsContext currentContext] setPatternPhase:NSMakePoint(0,[self frame].size.height)]; 
    [self.customBackgroundColour set]; 
    NSRectFill([self bounds]); 
    [theContext restoreGraphicsState]; 
} 

J'initialisés mon modèle de couleur de fond dans la méthode init:

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.customBackgroundColour = [NSColor colorWithPatternImage:[NSImage imageNamed:@"light-linen-texture.png"]]; 
    } 

    return self; 
} 
+1

Ajout de quelques mots clés pour aider les autres à trouver ceci: image de l'image en mosaïque to top/top pinning –

+0

Est-ce que quelqu'un sait ce qui pourrait amener le code à étirer le motif au lieu de l'incruster? J'ai remarqué que mon drawRect n'est pas appelé lorsque la vue est redimensionnée, peut-être que cela a quelque chose à voir avec ça? –

+0

Répondre à ma propre question dans le commentaire ci-dessus: Je devais rendre ma vue définie sur l'affichage des besoins à OUI chaque fois que son cadre a changé, et j'ai outrepassé setFrame lui-même pour le faire. Je ne suis pas sûr si c'est la manière normale de faire ceci, ou s'il y a un mécanisme intégré semblable à needsDisplayOnBoundsChange de CALayer, mais son fonctionnement. –

0

Découvrez RMSkinnedView sur Github!

EDIT: RMSkinnedView est une NSView sous-classe où vous pouvez configurer plusieurs options, y compris des coins arrondis, couleur de fond, motif d'image d'arrière-plan, etc., directement via le Runtime défini par utilisateur Attributs dans l'Interface Builder.