2013-02-26 4 views
7

私のアプリのコンテンツを扱うReeder/Sparrow風のUIを作成しようとしています。現在、NSSplitViewは2つのNSViewを内部で使用しています(左側はコンテンツのリスト、もう1つは「インスペクタ」です)。INAppStoreWindowタイトルバーのNSSplitViewディバイダ

私が知りたいのは、スプリットビューのディバイダとしても機能するタイトルバーにディバイダを作成する方法です。 私は既にINAppStoreWindowサブクラスを使用しています。

アイデア?ありがとう、事前

+0

達成しようとしているエフェクトのスクリーンショットを投稿してください。 – trojanfoe

答えて

8

に私はこれをやった方法はINAppStoreWindowのtileBarViewのサブビューとしてNSSplitViewサブクラスを追加することです:

// 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]; 

2つのトリッキーな部分は、この分割ビューは、タイトルバーのように動作することになっています(つまり、ウィンドウをドラッグすることができます)、ウィンドウ内のタイトルバーの分割ビューとメインの分割ビューを同期させることで、ユーザーと同じように見えます。

最初に解決するには、タイトルバー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 

2つ目の順序は、2つの分割ビューを同期させることです。メインコンテンツの分割ビューとタイトルバーの分割ビューの両方のデリゲートをコントローラクラス(おそらくウインドウコントローラですが、コードに意味をなさないもの)にします。次に、以下の2つの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

+0

@Andrew、awesome!あなたは私の日を作った:)ありがとう。 – siekfried

関連する問題