2010-07-28 2 views
4

Cela semble être une question si triviale à poser, mais ça me fâche un peu.Epingler la vue du document de NSScrollView lors du redimensionnement d'une fenêtre

J'ai une fenêtre qui contient une vue déroulante. Généralement, la vue de défilement a un documentView qui est verticalement plus grand que la vue de clip, ainsi vous obtenez un défilement vertical pour voir tout le contenu dans la vue de défilement. Lorsque je redimensionne la fenêtre, je recalcule la taille du contenu dans le documentView de la vue déroulante (car la vue défilante peut s'amincir, ce qui peut nécessiter une augmentation de la taille du documentView). Cependant, lorsque vous redimensionnez la fenêtre, le documentView conserve le bord visible inférieur avec le bord inférieur de la vue du clip (c'est-à-dire qu'il s'assure que la dernière ligne du texte est toujours visible). Ceci est un effet étrange, car les fenêtres maintiennent généralement le bord supérieur visible de la vue du document au même niveau que le bord supérieur de la vue du clip (la ligne de texte la plus haute de la vue du document reste épinglée en haut). Donc, ma première pensée pour résoudre ce problème était d'implémenter une fenêtre: windowDidResize: ou windowWillResize: toSize: notification, notez le delta entre la hauteur de l'ancienne fenêtre et la nouvelle hauteur, puis faites simplement défiler la vue de défilement afin de garder la ligne supérieure de la vue de défilement épinglé au sommet.

Cependant, pour une raison quelconque, cela ne semble pas fonctionner. Il fonctionne presque, mais certains deltas de redimensionnement semblent être un pixel désactivé, et si vous redimensionnez la fenêtre assez rapidement, il est parfois ~ 10 pixels d'arrêt. Donc, l'effet est que la ligne supérieure de la vue de défilement est presque épinglé au sommet, mais pas tout à fait, et il est distrayant.

Y a-t-il une meilleure façon de procéder? Voici le code approprié:

- (void)windowDidResize:(NSNotification *)notification; 
{ 
    if ([notification object] == mainWindow) { 
     CGFloat currentWindowHeight = [mainWindow frame].size.height; 

     // previousWindowHeight is an ivar 
     NSNumber *heightDeltaNum = [NSNumber numberWithFloat:(currentWindowHeight - previousWindowHeight)]; 
     previousWindowHeight = currentWindowHeight; 
     [[NSNotificationCenter defaultCenter] postNotificationName:@"AFSnapScrollView" object:heightDeltaNum]; 
    } 
} 

- (void)snapScrollViewNotification:(NSNotification *)theNotification; 
{ 
    [self snapScrollView]; 

    NSNumber *heightDeltaNum = [theNotification object]; 

    CGFloat newY = [[tagScrollView documentView] visibleRect].origin.y - [heightDeltaNum floatValue]; 
    NSPoint pointToScroll = NSMakePoint(0,newY); 
    [[tagScrollView documentView] scrollPoint:pointToScroll]; 
} 

- (void)snapScrollView; 
{ 

    [...] 

    // adjust the view frame 
    [[tagScrollView documentView] setFrame:NSMakeRect(0, 0, existingDocumentFrame.size.width, newDocumentViewHeight)]; 

    [...] 

} 
+0

Voir aussi http://stackoverflow.com/questions/2384014/nsscrollview-scroll-downward-when-resizing – charles

Répondre

10

Votre vue de document doit remplacer la méthode - (BOOL) isFlipped et retourner YES.

+0

Hm, ne se rendent pas compte que le comportement concerné des vues de défilement. Fonctionne parfaitement, fait exactement ce que je veux (une fois que j'ai modifié certaines parties de la méthode snapScrollView pour ajuster les coordonnées inversées). Merci beaucoup! –

0

La rotation du clipview n'a pas besoin de modifier documentView, après avoir coché les coordonnées.

@interface FlippedClipView : NSClipView 
@end 

@implementation FlippedClipView 
- (BOOL)isFlipped 
{ 
    return YES; 
} 
@end 
Questions connexes