Como faço para conectar o método de ação para um botão da barra de ferramentas do iPad Popover?

StackOverflow https://stackoverflow.com/questions/2588425

Pergunta

Estou usando o modelo de exibição dividida para criar uma visão simples de divisão que, é claro, um popover no modo retrato. Estou usando o código padrão gerado pelo modelo que adiciona/remove o item da barra de ferramentas e define o controlador de popover e o remove. Esses dois métodos são SplitViewController: WillSowViewController: ... e SplitViewController: WillHideViewController: ...

Estou tentando descobrir como fazer o popover desaparecer se o usuário tocar no botão da barra de ferramentas enquanto o popover for exibido. Você pode fazer com que o popover desapareça sem selecionar um item se você tocar em qualquer lugar fora do popover, mas eu também gostaria de fazê -lo desaparecer se o usuário tocar o botão novamente.

Onde estou preso é o seguinte: não parece haver uma maneira óbvia e fácil de conectar -se à ação do botão da barra de ferramentas. Posso dizer, usando o depurador, que a ação que está sendo chamada no botão é o showmasterInpopover. E sou novo em trabalhar com seletores programaticamente, admito.

De alguma forma, posso escrever uma ação e defini -la no item da barra de ferramentas sem substituir a ação que já está lá? Por exemplo, adicione uma ação que chama a que está lá agora? Ou eu teria que escrever uma ação que mostre/esconde o popover (comportamento que está sendo feito nos bastidores presumivelmente pelo controlador de visão dividida agora ???).

Ou estou perdendo uma maneira fácil de adicionar esse comportamento a este botão sem alterar o comportamento existente que está sendo configurado para mim?

Obrigada!

Foi útil?

Solução

Acontece que você pode fazer com que o popover descarte ao clicar no barbuttonitem implementando o método SplitViewController WillPresentViewController da seguinte maneira:

- (void) splitViewController:(UISplitViewController *)svc 
           popoverController: (UIPopoverController *)pc
   willPresentViewController: (UIViewController *)aViewController
{
    if (pc != nil) {
        [pc dismissPopoverAnimated:YES];
    }
}

Outras dicas

Portanto, o BarbuttonItem terá o UISPLITVIELCONTROLLER como alvo e showmasterInpopover: como a ação. Não consigo encontrá -lo na documentação, por isso estou um pouco preocupado que não seja bom chamá -lo, mas consegui funcionar alterando o alvo para si (o controlador de exibição) e a ação para um método personalizado, como isto:

- (void)showMasterInPopover:(id)sender {
    // ...insert custom stuff here...
    [splitViewController showMasterInPopover:sender];
}

Não tenha o representante para fazer um comentário real. :-(

@Jann - Tenho certeza de que o que Elizabeth quer fazer é bastante padrão. Por exemplo, o aplicativo Notas que os navios pré-carregados no iPad fecham e abre o popover quando você pressiona o botão da barra de ferramentas no canto superior esquerdo.

Abaixo está minha solução. Começa semelhante à solução de Greenisus, conectando o UISplitViewControllerManipulador de eventos da barra de ferramentas da barra de ferramentas. Eu uso um sinalizador no meu controlador para rastrear se o popover está aberto ou não. Finalmente, para lidar com o caso em que o usuário abre o popover, depois o fecha clicando fora do popover, implemento o UIPopoverControllerDelegate protocolo.

Primeiro, a interface do controlador:

@interface LaunchScene : NSObject <UISplitViewControllerDelegate, UIPopoverControllerDelegate>
{
    UISplitViewController* _splitViewController;    //Shows list UITableView on the left, and details on the right
    UIToolbar* _toolbar;                            //Toolbar for the button that will show the popover, when in portrait orientation
    SEL _svcAction;                                 //The action from the toolbar
    id _svcTarget;                                  //The target object from the toolbar
    UIPopoverController* _popover;                  //The popover that might need to be dismissed
    BOOL _popoverShowing;                           //Whether the popover is currently showing or not
}

-(void) svcToolbarClicked: (id)sender;

Eu uso _svcaction e _svcTarget para addess Greenisus se preocupar de que ele pode não estar chamando a função certa.

Abaixo está minha implementação. Para a brevidade, omiti o código que instancia o UisplitViewController e as subviews. Todo o código relacionado ao show/oculto é mostrado.

//the master view controller will be hidden so hook the popover
- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController:(UIPopoverController*)pc 
{   
    _popoverShowing = FALSE;
    if(_toolbar == nil) 
    {
        //set title of master button
        barButtonItem.title = @"Title goes here";

        //Impose my selector in between the SVController, and the SVController's default implementation
        _svcTarget = barButtonItem.target;
        _svcAction = barButtonItem.action;
        barButtonItem.target = self;
        barButtonItem.action = @selector(svcToolbarClicked:);

        //create a toolbar
        _toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 1024, 44)];
        [_toolbar setItems:[NSArray arrayWithObject:barButtonItem] animated:YES];
    }

    //add the toolbar to the details view (the second controller in the splitViewControllers array)
    UIViewController* temp = [_splitViewController.viewControllers objectAtIndex:1];
    [temp.view addSubview:_toolbar];
}

Aqui está minha função, que responde ao clique da barra de ferramentas. Isso lida com o caso em que o usuário toca e re-toca o botão da barra de ferramentas.

-(void) svcToolbarClicked: (id)sender
{
    if(_popoverShowing)
    {
        [_popover dismissPopoverAnimated:TRUE];
    }
    else 
    {
        //Perform the default SVController implementation
        [_svcTarget performSelector:_svcAction];
    }
    //Toggle the flag
    _popoverShowing = !_popoverShowing;
}

Algumas funções do uisplitViewControllerDelegate

//the master view (non-popover) will be shown again (meaning it is going to landscape orientation)
- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)button 
{
    //remove the toolbar
    [_toolbar removeFromSuperview];
}

// the master view controller will be displayed in a popover (i.e. the button has been pressed, and the popover is about to be displayed.  
//Unfortunately triggers when the popover is ALREADY displayed.
- (void)splitViewController:(UISplitViewController*)svc popoverController:(UIPopoverController*)pc willPresentViewController:(UIViewController *)aViewController 
{   
    _popover = pc; //Grab the popover object  
    _popover.delegate = self;
}

O código acima é suficiente para a maioria dos casos. No entanto, se o usuário abrir o popover, então descarta clicando em outras partes da tela, o _popoverShowing O Boolean conterá um valor incorreto, que forçará o usuário a tocar no botão da barra de ferramentas duas vezes para reabrir o popover. Para consertar isso, implemente o UIPopoverControllerDelegate Método, como o trecho abaixo.

//UIPopoverControllerDelegate method
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
    _popoverShowing = FALSE;
    _popover = nil;
}

Isso levou uma eternidade para descobrir, cavando os documentos e (acho) a maioria das perguntas do UISPLITVIEWController no StackOverflow. Espero que alguém ache isso útil. Nesse caso, cobiço pontos de reputação. ;-)

Talvez todos vocês apenas compliquem demais ou eu já li algo muito diferente do que vocês queriam fazer ... mas talvez seja isso que todos vocês estavam tentando descobrir tanto:

-(void)togglePopOverController {

if ([popOverController isPopoverVisible]) {

[popOverController dismissPopoverAnimated:YES];

} else {

[popOverController presentPopoverFromBarButtonItem:bbiOpenPopOver permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

}

}

Elisabeth escreve:

Você pode fazer com que o popover desapareça sem selecionar um item se você tocar em qualquer lugar fora do popover, mas eu também gostaria de fazê -lo desaparecer se o usuário tocar o botão novamente.

Primeiro de tudo, deixe -me dizer que nada do que estou prestes a dizer é ser tomado para o lado pessoal - isso não se entende dessa maneira. Tudo vem de anos de projetar interfaces de programação e estudar as diretrizes da interface humana da Apple (além de ter um designer gráfico que é contínuo tentando para me ensinar a maneira certa de fazer as coisas). É um ponto de vista oposto e não como um discurso retórico.

O que você está sugerindo é um problema em termos de interface do usuário para mim e será um problema que causa problemas quando a Apple revisar o aplicativo. Você nunca deve ter um objeto conhecido que ele execute uma função que ele não execute normalmente (por exemplo: um botão Nunca shows e depois libera uma visualização/objeto/janela. TOGLES FAÇA ISSO).

Por exemplo, uma lupa na barra de marinho significa pesquisa (conforme definido pela Apple). Eles têm no passado e continuarão no futuro para recusar aplicativos que o usam para ampliar a interface. Por exemplo: Apple rejeita o convertbot ou A Odisséia: Trilha das Lágrimas (pesquise na página). O idioma na rejeição é sempre o mesmo (marcando em negrito o que eles citariam para o seu uso):

“... usa imagens padrão de tela iPhone/iPod de maneira não padrão, potencialmente resultando em confusão do usuário. Alterando o comportamento dos gráficos padrão do iPhone, ações, e imagens, ou simular falhas desses gráficos, ações ou imagens, é uma violação do contrato do Programa de Desenvolveres para iPhone, que exige que os aplicativos cumpram as diretrizes da interface humana. ”

Além disso, se você realmente quer esse recurso, pergunte a si mesmo: "Por quê?". Se for porque você, você mesmo, eu realmente pularia. A maioria dos usuários ficaria confusa com esse comportamento e não o usaria porque Eles não sabiam que era uma opção usar. A Apple passou os últimos 3 anos treinando os usuários do iPhoneos como usar seus elementos de sistema operacional e interface. A última coisa que você, como programador ou designer, deseja fazer é gastar tempo tentando treinar um usuário sobre como usar seu aplicativo. Eles geralmente removem seu aplicativo do dispositivo e se movem para outro aplicativo semelhante, em vez de se forçar a aprender sua maneira de fazer as coisas.

Apenas meu $ 0,02

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top