2009-07-14 17 views
3

Je souhaite occasionnellement modifier les dimensions d'un NSView programmatique. Pour ce faire, il est utile d'obtenir les dimensions de différentes vues, de les ajuster les unes par rapport aux autres, puis d'utiliser setFrame: pour repositionner.Pourquoi la méthode frame d'un NSView renvoie-t-elle de mauvais résultats?

Le problème est que la méthode frame renvoie généralement des NSRects qui sont clairement erronés, de mon point de vue.

J'ai un programme avec un NSPanel mis en place dans Interface Builder et diverses connexions à mon programme principal. Pour tester les NSRects retournés par frame, j'ai ouvert le panneau dans la méthode awakeFromNib: de mon application, j'ai récupéré des NSRects et je les ai imprimés sur la console.

Voici mon awakeFromNib:

- (void)awakeFromNib { 
    NSLog(@"in awakeFromNib"); 
    [self showPrefsSheet:self]; //this is the prefs sheet with the controls of interest 
           //note that it does indeed pop up and is displayed 
    originalFrame = [aTextView frame]; 
    NSLog(@"the frame is %d, %d, %d, %d", originalFrame.origin.x, originalFrame.origin.y, originalFrame.size.width, originalFrame.size.height); 
    originalFrame = [aButton frame]; 
    NSLog(@"the frame is %d, %d, %d, %d", originalFrame.origin.x, originalFrame.origin.y, originalFrame.size.width, originalFrame.size.height); 
    return; 
    } 

Les résultats de ce code ressemblent à ceci dans la console:

in awakeFromNib 
the frame is 0, 0, 0, 0 
the frame is 0, 1079230464, 0, 1078329344 

Notez que (i) le panneau et les deux commandes sont affichées à l'écran ; (ii) Je sais pertinemment que les prises sont correctement connectées, parce que je peux faire des choses aux commandes par programme et les faire fonctionner; (iii) le constructeur de l'interface affiche des tailles d'image correctes dans l'inspecteur sous "Taille & Position".

En bref, tout le reste du programme fonctionne parfaitement. Il semble effectivement que les dimensions du cadre ne sont pas définies correctement ou quelque chose. Quelqu'un peut-il me dire comment récupérer les informations réelles sur les trames? Ou au moins expliquer les résultats que je vois?

Répondre

9

Les coordonnées du cadre sont flottantes, mais vos messages de journal utilisent% d. (ints).

changer la chaîne NSLog à:

@"the frame is %f, %f, %f, %f" 

Modifié:

Voici une macro très utile j'utiliser lors du débogage rects:

#define RECTLOG(rect) (NSLog(@"" #rect @" x:%f y:%f w:%f h:%f", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)); 

Vous pouvez alors faire les journaux rect facile:

RECTLOG([aTextView frame]); 
+0

Garçon, mon visage est rouge! Merci, Kailoa. Je me sens bête mais je suis content de pouvoir mettre ça derrière moi. – Dennis

+0

pas de problème. Je vais ajouter une macro qui est super utile aussi. – amattn

4

Lors de la journalisation d'un NSRect, n'oubliez pas que les champs sont des valeurs à virgule flottante et non des entiers.

Plutôt que d'écrire le format vous spécificateurs (soit en ligne ou par l'intermédiaire d'une macro), utilisez les fonctions que le cadre offre pour vous:

NSLog(@"frame - %@", NSStringFromRect([view frame])); 

Voir aussi:

NSStringFromSize 
NSStringFromPoint 
NSStringFromRange 

etc

+0

Je suis d'accord. Les méthodes 'NSStringFrom *' sont les meilleures à utiliser pour 'NSLog'ging. Ils vous donnent des résultats bien formatés. – Alex

+0

Oui, le seul problème est que NSStringFromRect génère un avertissement sur les projets iPhone. Sur l'iPhone, vous devez utiliser NSStringFromCGRect. De plus, avoir un wrapper de macro vous permet d'intégrer le nom de la variable. De toute façon fonctionne bien. – amattn

+0

Utilisez donc le type approprié NSStringFromCGRect si vous avez un CGRect. Ce n'est pas comme si vous ne connaissiez pas le type de la variable lorsque vous écrivez le code. Vérifiez également si NS_BUILD_32_LIKE_64 est applicable à ce que vous construisez et utilisez-le le cas échéant. –