2011-08-30 30 views
5

Tôi đang làm việc trên một ứng dụng cho OS X, nơi tôi sử dụng cửa sổ tùy chỉnh vẽ hình ảnh làm nền, bao gồm cả thanh tiêu đề. Tôi đã sửa đổi this code để vẽ cửa sổ và sau đó gọi [NSWindow standardWindowButton: forStyleMask:] để nhận các nút đóng, thu nhỏ và tối đa chuẩn.Ghi đè NSWindow nút đóng

Vấn đề là ứng dụng của tôi sử dụng NSPopovers và khi tôi đóng hoặc thu nhỏ ứng dụng trong khi cửa sổ bật lên, cửa sổ bật lên sẽ đóng cửa sổ bật lên hoặc hiển thị hoạt ảnh của cửa sổ bật lên thu nhỏ thay vì đóng ứng dụng. Có cách nào để ghi đè hành vi đóng/thu nhỏ mặc định trong NSWindow để tôi có thể loại bỏ mọi popovers mở trước không?

Cảm ơn và xin lỗi nếu đây là câu hỏi hiển nhiên - đây là lần đầu tiên tôi làm việc với SDK OS X nên tôi không có nhiều kinh nghiệm.

EDIT: Một vài giờ sau khi tôi đăng này tôi nghĩ rằng tôi đã có giải pháp rõ ràng - sử dụng phương pháp NSWindowDelegate "windowWillClose:" và "windowWillMiniaturize:" và bỏ qua những popovers đó. Tuy nhiên, có vẻ như là vì các nút đóng/thu nhỏ đóng cửa sổ bật lên, nếu một cửa sổ bật lên mở, các phương thức ủy nhiệm này sẽ không được gọi. Điều này đưa tôi trở lại bước 1, nhưng hy vọng biết được hành vi sẽ giúp ai đó tìm ra vấn đề.

Ngoài ra còn có một vấn đề khác với NSPopovers và tôi không biết nếu nó được kết nối hay không, vì vậy tôi nghĩ rằng tôi sẽ thêm nó ở đây chỉ trong trường hợp có một nguyên nhân phổ biến. Đôi khi, khi tôi cố gắng loại bỏ một cửa sổ bật lên, tôi sẽ gặp lỗi này (đối với ngữ cảnh, tôi đang nhấn một NSButton gọi một chức năng kiểm tra sự tồn tại của cửa sổ bật lên và nếu nó tồn tại, đóng nó):

2011-08-30 11:24:08.949 Playground[11194:707] *** Assertion failure in +[NSView _findFirstKeyViewInDirection:forKeyLoopGroupingView:], /SourceCache/AppKit/AppKit-1138/AppKit.subproj/NSView.m:11026 
2011-08-30 11:24:08.950 Playground[11194:707] this method is supposed to only be invoked on top level items 
2011-08-30 11:24:08.958 Playground[11194:707] (
    0 CoreFoundation      0x00007fff873d4986 __exceptionPreprocess + 198 
    1 libobjc.A.dylib      0x00007fff87ac6d5e objc_exception_throw + 43 
    2 CoreFoundation      0x00007fff873d47ba +[NSException raise:format:arguments:] + 106 
    3 Foundation       0x00007fff8950314f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 169 
    4 AppKit        0x00007fff88211064 +[NSView _findFirstKeyViewInDirection:forKeyLoopGroupingView:] + 137 
    5 AppKit        0x00007fff87d1f546 _replacementKeyViewAlongKeyViewPath + 565 
    6 AppKit        0x00007fff87d1f2ff -[NSView nextValidKeyView] + 179 
    7 AppKit        0x00007fff87d1f199 -[NSWindow _selectFirstKeyView] + 714 
    8 AppKit        0x00007fff882361cf _NSWindowRecursiveFindFirstResponder + 164 
    9 AppKit        0x00007fff882395c8 _NSWindowExchange + 79 
    10 AppKit        0x00007fff883a7e3a -[_NSWindowTransformAnimation startAnimation] + 426 
    11 AppKit        0x00007fff87c98bb2 -[NSWindow _doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 592 
    12 AppKit        0x00007fff87c9890f -[NSWindow orderWindow:relativeTo:] + 154 
    13 AppKit        0x00007fff883dfaf0 _NSPopoverCloseAndAnimate + 948 
    14 Playground       0x00000001000078a4 -[MainWindowController dismissPopover:] + 100 
    15 Playgorund       0x0000000100007012 -[MainWindowController requestWasClicked:] + 98 
    16 CoreFoundation      0x00007fff873c411d -[NSObject performSelector:withObject:] + 61 
    17 AppKit        0x00007fff87ca2852 -[NSApplication sendAction:to:from:] + 139 
    18 AppKit        0x00007fff87ca2784 -[NSControl sendAction:to:] + 88 
    19 AppKit        0x00007fff87ca26af -[NSCell _sendActionFrom:] + 137 
    20 AppKit        0x00007fff87ca1b7a -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2014 
    21 AppKit        0x00007fff87d2157c -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 489 
    22 AppKit        0x00007fff87ca0786 -[NSControl mouseDown:] + 786 
    23 AppKit        0x00007fff87c6b66e -[NSWindow sendEvent:] + 6280 
    24 AppKit        0x00007fff87c03f19 -[NSApplication sendEvent:] + 5665 
    25 AppKit        0x00007fff87b9a42b -[NSApplication run] + 548 
    26 AppKit        0x00007fff87e1852a NSApplicationMain + 867 
    27 Playground       0x0000000100001c52 main + 34 
    28 Playground       0x0000000100001c24 start + 52 
    29 ???         0x0000000000000001 0x0 + 1 
) 

Trả lời

3

Giải pháp hóa ra khá đơn giản.

Khi tôi tạo ra các nút trên NSWindow, tôi đã thay đổi hành động và mục tiêu của các nút:

[closeButton setTarget:self.delegate]; // alternatively you can make it self.windowController 
[closeButton setAction:@selector(closeThisWindow:)]; 

Và sau đó trong lớp con NSWindowController, tôi thực hiện phương pháp này:

-(void)closeThisWindow { 
    [self close]; // for the minimize button you'll call [self.window miniaturize] 
} 

Đối một số lý do, NSPopovers luôn xuất hiện trở lại khi cửa sổ được mở lại hoặc chưa được tối ưu hóa; vì tôi thực sự muốn hành vi này trong ứng dụng của tôi, nó không phải là một vấn đề, nhưng nó là một cái gì đó để ghi nhớ nếu bạn sử dụng giải pháp này. Nếu bạn không có bất kỳ cửa sổ con, sau đó bạn chỉ có thể lặp qua self.window.childWindows vì NSPopovers được coi là cửa sổ con. Nếu bạn có các cửa sổ con khác mà bạn muốn xử lý riêng, bạn có thể thêm một mảng vào lớp con NSWindow để theo dõi tất cả các cửa sổ bật lên của bạn và chỉ cần lặp lại thông qua đó.

+0

Nhưng ... về dấu vết ngăn xếp thì sao ?! TÔI CẦN BIẾT. –

+0

@ Big-OClaire Thật không may, câu hỏi này là nhận được gần 6 tuổi và tôi thực sự không có quyền truy cập vào mã nguồn nữa, vì vậy tôi không thể giúp bạn. Lấy làm tiếc! – Aaron