2012-01-29 27 views
17

Tôi đang tạo ứng dụng nằm trong thanh trạng thái. Khi mục trạng thái được nhấp, NSPopover bật lên.NSPopover transiency khi cửa sổ bật lên đang ở trong thanh trạng thái

Nó trông như thế này:

enter image description here

Dưới đây là các vấn đề: Tôi muốn nó được "thoáng", có nghĩa là nếu tôi bấm bất cứ nơi nào bên ngoài của popover, nó sẽ đóng lại. Và trong khi NSPopoverBehaviorTransient hoạt động tốt khi popover nằm trong một cửa sổ, nó không hoạt động khi nó ở trong thanh trạng thái.

Làm cách nào để tự mình thực hiện hành vi như vậy?

Trả lời

28

Nó bật ra được dễ dàng:

- (IBAction)openPopover:(id)sender 
{ 
    // (open popover) 

    if(popoverTransiencyMonitor == nil) 
    { 
     popoverTransiencyMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask handler:^(NSEvent* event) 
            { 
             [self closePopover:sender]; 
            }]; 
    } 
} 

- (IBAction)closePopover:(id)sender 
{ 
    if(popoverTransiencyMonitor) 
    { 
     [NSEvent removeMonitor:popoverTransiencyMonitor]; 

     popoverTransiencyMonitor = nil; 
    } 

    // (close popover) 
} 

gì là không dễ dàng, tuy nhiên, là có những vấn đề khó chịu với việc có một cửa sổ pop popover ra khỏi NSStatusItem (nó đã không cư xử như mong muốn khi Sứ mệnh Điều khiển được gọi hoặc không gian chuyển sang cửa sổ toàn màn hình). Tôi đã phải thực hiện một cửa sổ tùy chỉnh luôn luôn nổi trên NSStatusItem và giao dịch với chuyển sang một cửa sổ toàn màn hình vv. Có vẻ dễ dàng, nhưng các mục trạng thái rõ ràng không được thiết kế cho một cái gì đó như thế;)

+5

Đối với hành vi nhất quán với hành vi của các mục trạng thái hệ thống: 'addGlobalMonitorForEventsMatchingMask: NSLeftMouseDownMask | NSRightMouseDownMask' - để các nhấp chuột phải cũng đóng cửa sổ bật lên. – inket

7

Cách tiếp cận Tôi sử dụng là tương tự như câu trả lời ở trên, ngoại trừ tôi có tất cả mọi thứ kết hợp thành một phương pháp thay vì sử dụng hai IBActions riêng biệt.

Trước tiên, tôi tuyên bố các thuộc tính sau

@property (strong, nonatomic) NSStatusItem *statusItem; 
@property (strong, nonatomic) NSEvent *popoverTransiencyMonitor; 
@property (weak, nonatomic) IBOutlet NSPopover *popover; 
@property (weak, nonatomic) IBOutlet NSView *popoverView; 

sau đó trong awakeFromNib tôi thiết lập các mục trên thanh trạng thái

- (void)awakeFromNib { 

    self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; 

    self.statusItem.title = @"Title"; 
    self.statusItem.highlightMode = YES; 
    self.statusItem.action = @selector(itemClicked:); 
} 

tiếp theo là phương pháp đó được gọi là khi mục thanh trạng thái được nhấp

- (void)itemClicked:(id)sender { 

    [[self popover] showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMinYEdge]; 

    if (self.popoverTransiencyMonitor == nil) { 
     self.popoverTransiencyMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDownMask | NSRightMouseDownMask | NSKeyUpMask) handler:^(NSEvent* event) { 
      [NSEvent removeMonitor:self.popoverTransiencyMonitor]; 
      self.popoverTransiencyMonitor = nil; 
      [self.popover close]; 
     }]; 
    } 
} 

làm cho cửa sổ bật lên xuất hiện và cũng đóng khi người dùng nhấp ngoài tầm nhìn.

Lưu ý rằng trong Trình tạo giao diện, bạn phải đặt hành vi của cửa sổ bật lên thành Tạm thời để cửa sổ bật lên sẽ đóng khi người dùng nhấp vào mục trạng thái.

Các vấn đề liên quan