2013-02-26 14 views
7

Próbuję utworzyć interfejs użytkownika Reeder/Sparrow do obsługi zawartości mojej aplikacji. Obecnie używam NSSplitView z dwoma NSView w środku (ten po lewej jest listą treści, a drugi po prawej to "inspektor").Rozdzielacz NSSplitView na pasku tytułowym INAppStoreWindow

Chciałbym wiedzieć, jak utworzyć dzielnik na pasku tytułu, który działa również jako dzielnik widoku podzielonego. Używam już podklasy INAppStoreWindow.

Wszelkie pomysły? Niż z góry

+0

Proszę zgłoś zrzut ekranu o efektach, które próbujesz osiągnąć. – trojanfoe

Odpowiedz

8

Sposób robiłem tego celu jest dodanie podklasy NSSplitView jako podrzędny Spośród INAppStoreWindow za tileBarView:

// This code comes from the INAppStoreWindow readme 
INAppStoreWindow *appStoreWindow = (INAppStoreWindow *)[self window]; 

// self.titleView is a an IBOutlet to an NSView that has been configured in IB with everything you want in the title bar 
self.windowTitleBarView.frame = appStoreWindow.titleBarView.bounds; 
self.windowTitleBarView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; 
[appStoreWindow.titleBarView addSubview:self.windowTitleBarView]; 

Obie części skomplikowane są uzyskiwanie tego widoku podzielonego, aby zachowywać się jak pasku tytułowym (tzn. nadal pozwala przeciągnąć okno dookoła) i synchronizuje widok podzielony na pasku tytułu z głównym widokiem podziału w oknie, więc wydaje się, że jest to samo dla użytkownika.

Aby rozwiązać pierwszy problem, musisz wykonać więcej niż tylko TAK z poziomu -mouseDownCanMovewWindow w pasku tytułowym podklasy NSSplitView. Jeśli to zrobisz, żaden z podrzędnych podglądów na pasku kafelków nie zareaguje na zdarzenia myszy. Zamiast tego wykonaj następujące czynności:

@implementation MyTitleBarSplitView 

- (BOOL)mouseDownCanMoveWindow 
{ 
    return NO; 
} 

// Code below adapted from http://www.cocoabuilder.com/archive/cocoa/219261-conditional-mousedowncanmovewindow-for-nsview.html 
- (void)mouseDown:(NSEvent*)theEvent 
{ 
    NSWindow *window = [self window]; 
    NSPoint mouseLocation = [theEvent locationInWindow]; 
    NSRect dividerRect = NSMakeRect(NSMaxX([[[self subviews] objectAtIndex:0] frame]), 
            NSMinY([self bounds]), 
            [self dividerThickness], 
            NSHeight([self bounds])); 
    dividerRect = NSInsetRect(dividerRect, -2, 0); 
    NSPoint mouseLocationInMyCoords = [self convertPoint:mouseLocation fromView:nil]; 
    if (![self mouse:mouseLocationInMyCoords inRect:dividerRect]) 
    { 
     mouseLocation = [window convertBaseToScreen:mouseLocation]; 
     NSPoint origin = [window frame].origin; 
     // Now we loop handling mouse events until we get a mouse up event. 
     while ((theEvent = [NSApp nextEventMatchingMask:NSLeftMouseDownMask|NSLeftMouseDraggedMask|NSLeftMouseUpMask untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES])&&([theEvent type]!=NSLeftMouseUp)) 
     { 
      @autoreleasepool 
      { 
       NSPoint currentLocation = [window convertBaseToScreen:[theEvent locationInWindow]]; 
       origin.x += currentLocation.x-mouseLocation.x; 
       origin.y += currentLocation.y-mouseLocation.y; 
       // Move the window by the mouse displacement since the last event. 
       [window setFrameOrigin:origin]; 
       mouseLocation = currentLocation; 
      } 
     } 
     [self mouseUp:theEvent]; 
     return; 
    } 

    [super mouseDown:theEvent]; 
} 

@end 

Druga kolejność to synchronizacja dwóch widoków podziału. Ustaw swoją klasę kontrolera (prawdopodobnie kontroler okna, ale co ma sens w kodzie) delegata zarówno głównego widoku dzielonego treści, jak i podzielonego widoku paska tytułu. Następnie zaimplementuj dwie metody przekazywania delegatów NSSplitView:

@implementation MyController 
{ 
    BOOL updatingLinkedSplitview; 
} 

- (CGFloat)splitView:(NSSplitView *)splitView constrainSplitPosition:(CGFloat)proposedPosition ofSubviewAt:(NSInteger)dividerIndex 
{ 
    // If already updating a split view, return early to avoid infinite loop and stack overflow 
    if (updatingLinkedSplitview) return proposedPosition; 

    if (splitView == self.mainSplitView) 
    { 
     // Main splitview is being resized, so manually resize the title bar split view 
     updatingLinkedSplitview = YES; 
     [self.titleBarSplitView setPosition:proposedPosition ofDividerAtIndex:dividerIndex]; 
     updatingLinkedSplitview = NO; 
    } 
    else if (splitView == self.titleBarSplitView) 
    { 
     // Title bar splitview is being resized, so manually resize the main split view 
     updatingLinkedSplitview = YES; 
     [self.mainSplitView setPosition:proposedPosition ofDividerAtIndex:dividerIndex]; 
     updatingLinkedSplitview = NO; 
    } 

    return proposedPosition; 
} 

- (void)splitView:(NSSplitView *)splitView resizeSubviewsWithOldSize:(NSSize)oldSize 
{ 
    // This is to synchronize the splitter positions when the window is first loaded 
    if (splitView == self.titleBarSplitView) 
    { 
     NSRect leftFrame = NSMakeRect(NSMinX([self.leftTitleBarView frame]), 
             NSMinY([self.leftTitleBarView frame]), 
             NSWidth([self.leftMainSplitView frame]), 
             NSHeight([self.leftTitleBarView frame])); 
     NSRect rightFrame = NSMakeRect(NSMaxX(leftFrame) + [splitView dividerThickness], 
             NSMinY([self.rightTitleBarView frame]), 
             NSWidth([self.rightMainSplitView frame]), 
             NSHeight([self.rightTitleBarView frame])); 

     [self.leftTitleBarView setFrame:leftFrame]; 
     [self.rightTitleBarView setFrame:rightFrame]; 
    } 
} 
+0

Thanx! Właśnie tego szukałem! – psicosis

+0

@Andrew, niesamowite! Zrobiłeś mój dzień :) Wielkie dzięki. – siekfried

Powiązane problemy