2011-01-15 7 views
5

Ich hatte einen meiner Kollegen heute mit einem Problem zu mir kommen, wie kann er laden oder view-swap documentView von NSScrollView, so dass die geladene Ansicht erscheint fix an der oberen linken Ecke anstelle der unteren Ecke.Einstellung NSScrollView Inhalt oben links statt unten links beim Dokumentwechsel

Er hatte eine Weile im Internet gesucht und herumgetrottet und hatte keine Lösung, obwohl er die Dokumentation bei Apple, StackOverflow und anderen Orten gelesen hatte.

Hier ist das Problem Stück-für-Stück:

In Interface Builder ziehen Sie ein NSScrollView in das Projekt. auch im Interface Builder ziehen zwei benutzerdefinierte Ansichten in das Projekt und fügen Sie einige Textfelder, Schaltflächen usw.

eine Controller-Klasse erstellen (zB MyController) mit folgenden IBOutlet s:

  • IBOutlet NSScrollView * myScrollView
  • IBOutlet NSView * myCustomView1
  • IBOutlet NSView * myCustomView2

den Auslässen der CONNECT Steuerelemente im Interface Builder.

Eine NSView Unterklasse der documentView Flip:

@implementation myFlippedView 

-(id)initWithFrame:(NSRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code here. 
    } 
    return self; 
} 

-(void)drawRect:(NSRect)dirtyRect { 
    // Drawing code here. 
} 

-(BOOL)isFlipped { 
    return YES; 
} 

Wählen Sie die documentView des NSScrollView im Interface Builder und es eine Unterklasse von myFlippedView machen. In Interface Builder würden Sie die NSScrollView auswählen und dann erneut darauf klicken, um zur documentView zu gelangen, oder die IB-Bibliothek ändern, um eine Strukturansicht anzuzeigen und die untergeordnete benutzerdefinierte Ansicht von NSScrollView auszuwählen.

Im myController Klasse tauscht die Ansichten mit den folgenden Methoden:

-(void)awakeFromNib { 

    [myScrollView setDocumentView:myCustomView1]; 
} 

-(IBAction)swapViews:(id)sender { 

    if ([myScrollView documentView] == myCustomView1) { 

     [myScrollView setDocumentView:myCustomView2]; 

    } else { 

     [myScrollView setDocumentView:myCustomView1]; 

    } 
} 

schließlich eine Schaltfläche in einem Projekt der Aktion swapViews anschließen, erstellen und ausführen.

Das Problem ist, dass die Koordinaten nicht aufgelöst wurden, wie es mit dem IsFlipped erwartet wurde.

Antwort

7

Es gibt einen einfachen, aber scheinbar oft übersehenen Grund dafür.

Obwohl isFlipped die benutzerdefinierte Ansicht in Interface Builder ableitet, wird documentView in der Ansichtswap ersetzt, von denen die erste unter awakeFromNib verwendet wird.

Die Lösung besteht darin, myCustomClass1 und myCustomClass2 von der Klasse myFlippedView abzuleiten.

Tun Sie dies und testen Sie es und Sie werden feststellen, dass die Ansichten jetzt oben links in der Bildlaufansicht angezeigt werden. Es hat jedoch ein neues Problem geschaffen. Der gesamte Inhalt in der benutzerdefinierten Ansicht ist jetzt von unten nach oben angeordnet (da standardmäßig alle NSView Layouts von unten links sind, also dreht das Spiegeln auch ihre Koordinaten).

Glücklicherweise gibt es eine weitere einfache Lösung für dieses Problem. Lesen Sie weiter :-)

Markieren Sie im Interface Builder alle Steuerelemente in myCustomView1, und wählen Sie im Menü Layout die Option Objekte in -> Benutzerdefinierte Ansicht einbetten aus. Ändern Sie die Größe nach Bedarf, machen Sie dasselbe für myCustomView2 und erstellen Sie es neu.

Voila. Eine NSScrollView mit der Inhaltsansicht wird ausgetauscht und erscheint oben links in der Bildlaufansicht statt unten links.

+1

Oder Sie könnten die einfachere Route gehen und die getauschten Ansichten nur eine Unteransicht der myFlippedView machen, anstatt sie zur Dokumentansicht zu machen. – ughoavgfhw

+0

Das könnte man. Guter Punkt. – Hooligancat

+0

Dies führt jedoch zu einem neuen Problem. Wenn Sie die Bildlaufansicht durch Größenänderung eines Fensters kleiner als die Dokumentansicht machen, wird sie an den unteren Rand der Ansicht angefügt und nicht an den Anfang. Als Benutzer erwartet man Letzteres. –

0

Um richtig zu machen die documentView zunächst an die Spitze des Scroll ausrichten und auch Stift es nach oben, wenn die documentView kleiner ist, als es Clipview ist, das ist, was für mich funktioniert:

1 - In Interface Builder umschließen alle Steuerelemente in Ihrem documentView in einer benutzerdefiniertenNSView Instanz. (KEIN blätterte Ansicht)

2 - Erstellen Sie eine NSView Unterklasse für die documentView verwendet werden soll, und überschreiben diese Methoden:

- (BOOL)isFlipped { 
    return YES; 
} 
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize { 
CGFloat superViewHeight = self.superview.frame.size.height, height = self.frame.size.height; 
    if(superViewHeight>height) { 
     [self setFrameOrigin:NSMakePoint(self.frame.origin.x, superViewHeight-height)]; 
    } 
} 

Die Unterklasse Ansicht sollte documentView die scrollViews sein, die zweite enthält (normal) NSView, das alle Steuerelemente enthält.