2013-02-26 49 views
7

我正在嘗試創建一個Reeder/Sparrow-like UI來處理我的應用程序的內容。目前我使用內部含有兩個NSView的NSSplitView(左邊的是內容列表,右邊的是「檢查員」)。INAppStoreWindow標題欄上的NSSplitView分隔線

我想知道的是如何在標題欄上創建分隔符,該分隔符也是分隔視圖的分隔符。 我已經在使用INAppStoreWindow子類。

任何想法? Thanx提前

+0

請張貼的你想達到的效果的屏幕截圖。 – trojanfoe 2013-02-26 15:44:20

回答

8

我這樣做是爲了增加一個NSSplitView子作爲INAppStoreWindow的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]; 

兩個棘手的部分收到此拆分視圖表現得像一個標題欄(即仍允許拖動窗口),並將標題欄中的分割視圖與窗口中的主分割視圖同步,以使它們對用戶來說看起來是一樣的。

要解決第一個問題,您必須做的不僅僅是從標題欄NSSplitView子類中的-mouseDownCanMovewWindow返回YES。如果你這樣做,那麼沒有任何視圖欄的子視圖會響應鼠標事件。相反,請執行以下操作:

@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 

業務的第二順序是同步兩個拆分視圖。製作你的控制器類(可能是窗口控制器,但無論你的代碼是否合理),你的主內容拆分視圖和標題欄拆分視圖的委託。然後,執行以下兩個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!這正是我正在尋找的! – psicosis 2013-02-26 19:20:18

+0

@安德魯,真棒!你讓我的一天:)非常感謝。 – siekfried 2013-12-06 13:00:49