popUpContextMenu относительно кнопки, когда меню будет переполняться за пределами экрана?

#objective-c #cocoa

#objective-c #cocoa

Вопрос:

Я пытаюсь показать, NSMenu когда нажата кнопка, чтобы показать некоторые параметры общего доступа (я не могу использовать NSSharingServicePicker , потому что мне нужно создавать разделяемые элементы в фоновом режиме). Я делаю это с помощью простого IBAction :

 - (IBAction)showShareSheet:(id)sender{
    NSRect frame = [(NSButton *)sender frame];
    NSPoint menuOrigin = [[sender superview] convertPoint:NSMakePoint(
        frame.origin.x, 
        frame.origin.y   frame.size.height   95
    ) toView:self.dataView];
    NSEvent *event = [NSEvent mouseEventWithType:
        NSLeftMouseDown
        location:menuOrigin
        modifierFlags:(int)nil
        timestamp:0
        windowNumber:[[(NSButton *)sender window] windowNumber]
        context:[[(NSButton *)sender window] graphicsContext]
        eventNumber:0
        clickCount:1
        pressure:1
    ];
    [NSMenu popUpContextMenu:theMenu withEvent:event forView:sender];
}
  

Обычно это работает нормально, если окно не находится слишком близко к краю экрана. Когда это происходит, нормальная позиция перемещается, потому что для размещения меню недостаточно места:

http://i.imgur.com/4DFS6EO.jpg
http://i.imgur.com/yeN9dVx.jpg?1

Я несколько исправил это, определив переполнение:

 float marginRight = NSScreen.mainScreen.frame.size.width - (self.window.frame.origin.x   self.window.frame.size.width);
float overflow = self.window.frame.size.width   marginRight - frame.origin.x  - theMenu.size.width - 7;
float difference = 0;
if (overflow < 0){
    difference = overflow;
}
  

Затем добавление difference к frame.origin.x (фактически вычитание), но это уродливое исправление. Мои вычисления также отключены, поэтому мне нужно вычесть 7.

Я упускаю из виду более эффективный способ позиционирования меню относительно кнопки? Метод NSShaingServicePicker showRelativeToRect: рассчитал это для меня за кулисами и не требует от меня никаких дополнительных вычислений, чтобы избежать прыжков.