Как программно закрыть NSPopover

Я хочу знать, как закрыть NSPopover программно, не касаясь снаружи, потому что я хочу назначить его действию (например, KeyDown Enter Key или другому ярлыку)

т.к. свой NSPopover я открываю с помощью ярлыка, было бы логичнее закрыть нажатием другой команды

собираюсь поделиться своим кодом:

EdiciondeCuentasWC.h (NSWindowController), откуда я вызываю свой NSPopover

#import "EdicionDeCuentasWC.h"
#import "CambiarTipoCuentaVC.h"
@interface EdicionDeCuentasWC ()<NSPopoverDelegate>{
    CambiarTipoCuentaVC         *cambiarTipoCuentaVC;
}
@property (strong) IBOutlet NSPopover *popoverClasifCuentas;

@end


@implementation EdicionDeCuentasWC

-(void)mostrarPopupCambiarTipoCta{

        cambiarTipoCuentaVC = (CambiarTipoCuentaVC *) _popoverCambiarTipoCuentas.contentViewController;
        cambiarTipoCuentaVC.nombre_tipo_cta  = arrayActivos[renglonSeleccionado][@"nombre_tipo_cta"];
        cambiarTipoCuentaVC.prioridad_cta    = arrayActivos[renglonSeleccionado][@"prioridad_cta"];

        NSTableCellView *cellView = [_activoTableView viewAtColumn:0
                                                               row:renglonSeleccionado
                                                   makeIfNecessary:NO];

        [_popoverClasifCuentas      setDelegate:self];
        [cambiarTipoCuentaVC        inicializarDatos];
        [_popoverCambiarTipoCuentas showRelativeToRect:[cellView bounds] ofView:cellView preferredEdge:NSMaxXEdge];
}

#pragma mark NSPopoverDelegate
-(void)popoverWillClose:(NSNotification *)notification{

    NSPopover *popover = (NSPopover *)[notification object]; //there I have the code for managing all the returning parameters...

}

@end

И код моего NSPopover находится внутри NSViewController (CambiarTipoCuentaVC), но внутри у меня нет ни [self close], ни [self PerformClose], чтобы закрыть его с помощью кнопки или ярлыка, любая помощь, чтобы заставить его работать, я был бы признателен ...


person Jesus    schedule 05.08.2014    source источник


Ответы (4)


Вы хотя бы заглянули в документацию NSPopover? У него есть метод -close и метод -performClose: для немного другой цели.

person Ken Thomases    schedule 06.08.2014
comment
дело в том... У меня есть все мои программы внутри NSViewController, и ни [self close], ни [self PerformClose] не собираются загружать мой код - person Jesus; 06.08.2014
comment
Сообщения не обязательно должны отправляться на self. Учитывая, что у вас есть ссылка на всплывающее окно, вы можете отправить ему сообщение, используя эту ссылку. - person Ken Thomases; 06.08.2014

Я наткнулся на этот пост и хотел поделиться своим решением.

>macOS 10.10, Swift 4

Начиная с macOS 10.10 вы можете позвонить

presentViewController(_ viewController: NSViewController, asPopoverRelativeTo positioningRect: NSRect, of positioningView: NSView, preferredEdge: NSRectEdge, behavior: NSPopoverBehavior)

на NSViewController, чтобы представить другой контроллер представления в качестве всплывающего окна.

Когда вы это сделаете, представляемый контроллер представления будет доступен через свойство presenting. Таким образом, вам нужно только вызвать presenting?.dismissViewController(self), чтобы закрыть всплывающее окно.

Я надеюсь, что это полезно для тех, кто ищет современное решение этой проблемы.

person JanApotheker    schedule 24.02.2017
comment
В Swift 4.2 он представляет ViewController?.dismiss(self), но в остальном спасибо за это - я нахожу его более плавным и чуть быстрее, чем мое решение. - person green_knight; 06.07.2020

То, что вы хотите закрыть, - это окно вашего всплывающего окна, поэтому вы можете просто добавить

@IBAction func closePopover(_ sender: Any) {
    self.view.window?.performClose(sender)
}

к контроллеру представления вашего всплывающего окна, подклассы не требуются.

(Xcode 10, macOS 10.13, Swift 4.1)

отредактировано для добавления: я попробовал решение JanApotheker с использованием presentingViewController?.dismiss(self), и оно немного быстрее и плавнее, чем мое, поэтому я больше не рекомендую его.

person green_knight    schedule 14.06.2018
comment
Это было трудно найти, но я очень благодарен. - person ICL1901; 18.02.2020

Я нашел, как я собираюсь дополнить ответ Кена Томаса

Я создал подкласс NSPopover под названием MyNSPopover.

затем я добавил следующий код:

#import "MyNSPopover.h"

@implementation MyNSPopover

-(void)keyDown:(NSEvent *)theEvent{

    //if enter key is pressed, the NSPopup will be closed
    if (theEvent.keyCode == 36) {
        [self close];
    }
}

@end

а затем просто добавил этот класс в мой NSPopover, как это

введите здесь описание изображения

сделано просто работает

person Jesus    schedule 06.08.2014