Comment puis-je brancher dans la méthode d'action pour un bouton de la barre d'outils popover iPad?

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

Question

J'utilise le modèle de vue partagé pour créer une vue simple split qui a, bien sûr, un popover en mode Portrait. J'utilise le code par défaut généré par modèle qui ajoute / supprime l'élément de la barre d'outils et définit le contrôleur popover et supprime. Ces deux méthodes sont splitViewController: willShowViewController: ... et splitViewController: willHideViewController: ...

Je suis en train de comprendre comment faire disparaître la popover si l'utilisateur tape sur le bouton de la barre d'outils tandis que le popover est affiché. Vous pouvez faire la popover disparaître sans sélectionner un élément si vous tapez hors du popover, mais je voudrais aussi faire disparaître si l'utilisateur tape à nouveau sur le bouton.

Là où je suis coincé est ceci: il ne semble pas être une évidence, facile à accrocher dans l'action pour le bouton de la barre d'outils. Je peux dire, en utilisant le débogueur, que l'action qui est appelée sur le bouton est showMasterInPopover. Je suis nouveau à travailler avec sélecteurs programme, je l'avoue.

Puis-je écrire en quelque sorte une action et le mettre sur l'élément de la barre d'outils sans écraser l'action qui est déjà là? par exemple. ajouter une action qui appelle celui qui est là maintenant? Ou devrais-je écrire une action qui montre / cache le popover moi-même (comportement qui se fait dans les coulisses vraisemblablement par le contrôleur de vue partagé maintenant ???).

Ou suis-je manque un moyen facile d'ajouter ce comportement à ce bouton sans changer le comportement existant qui est actuellement mis en place pour moi?

Merci!

Était-ce utile?

La solution

Alors il se avère que vous pouvez faire le popover rejeter en cliquant sur le barButtonItem en mettant en œuvre la méthode SplitViewController willPresentViewController comme suit:

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

Autres conseils

Ainsi, le barButtonItem aura le UISplitViewController comme cible et showMasterInPopover: comme l'action. Je ne peux pas le trouver dans la documentation, donc je suis un peu inquiet ce n'est pas correct de l'appeler, mais je l'ai eu à travailler en changeant la cible à l'auto (le contrôleur de vue) et l'action à une méthode personnalisée, comme ceci:

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

Ne pas avoir le représentant de faire un vrai commentaire. : - (

@Jann - Je suis sûr de ce que Elizabeth veut faire est assez standard. Par exemple, l'application Notes que les navires pré-chargés sur l'iPad ferme et ouvre la popover lorsque vous appuyez sur le bouton de la barre d'outils dans le coin en haut à gauche.

Voici ma solution. Il commence même à la solution greenisus', en accrochant événement bouton barre d'outils du UISplitViewController du gestionnaire. J'utilise un drapeau dans mon contrôleur afin de déterminer si le popover est ouvert ou non. Enfin, pour gérer le cas où l'utilisateur ouvre le popover, puis ferme en cliquant en dehors du popover, je mets en œuvre le protocole UIPopoverControllerDelegate.

Tout d'abord, l'interface du contrôleur:

@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;

J'utilise _svcAction et _svcTarget à addess soucis de greenisus qu'il pourrait ne pas être d'appeler la fonction droite.

Ci-dessous ma mise en œuvre. Par souci de concision, j'ai omis le code qui instancie le UISplitViewController et les sous-vues. Tout le code lié affichage / masquage est représentée.

//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];
}

Voici ma fonction, qui répond à la barre d'outils cliquez. Cela gère le cas où les robinets d'utilisateur et re-tap sur le bouton de la barre d'outils.

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

Certaines fonctions de 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;
}

Le code ci-dessus est suffisant pour la plupart des cas. Toutefois, si l'utilisateur ouvre le popover, puis congédie en cliquant ailleurs sur l'écran, le booléen _popoverShowing contiendra une valeur incorrecte, ce qui forcera l'utilisateur à appuyer sur le bouton de la barre d'outils à deux reprises pour rouvrir le popover. Pour résoudre ce problème, mettre en œuvre la méthode de UIPopoverControllerDelegate, comme l'extrait ci-dessous.

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

Cela m'a pris une éternité pour comprendre, creuser à travers les documents et (je pense) la plupart des questions UISplitViewController sur StackOverflow. J'espère que quelqu'un juge utile. Si oui, je convoite des points de réputation. ; -)

Peut-être que tout simplement compliquez trop ou j'ai lu quelque chose de très différent que les gars ont voulu faire ... mais peut-être, c'est ce que vous étiez tous à essayer de comprendre si hardish:

-(void)togglePopOverController {

if ([popOverController isPopoverVisible]) {

[popOverController dismissPopoverAnimated:YES];

} else {

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

}

}

Elisabeth écrit:

  

Vous pouvez faire la popover disparaître sans sélectionner un élément si vous tapez hors du popover, mais je voudrais aussi faire disparaître si l'utilisateur tape à nouveau sur le bouton.

Tout d'abord, permettez-moi de dire que rien de ce que je vais dire est à prendre personnellement - il est censé pas de cette façon. Tout vient des années de la conception d'interfaces de programmation et à l'étude Human Interface Guidelines d'Apple (ainsi que d'avoir un concepteur graphique qui est contstantly essayer pour me enseigner la bonne façon de faire les choses). Il est conçu comme un point de vue opposé et non comme une diatribe.

Ce que vous proposez est moi-UI sage problème, et un problème qui cause des problèmes quand Apple examine l'application. Vous n'êtes jamais censé avoir une interface utilisateur-objet connu exécuter une fonction qui ne fonctionne pas normalement (par exemple: un bouton jamais montre et libère une vue / objet / fenêtre. Alterne faire).

Par exemple, une loupe sur la barre de navigation moyens de recherche (tel que défini par Apple). Ils ont dans le passé, et continuera à l'avenir, refuser des applications qui utilisent ce pour zoomer l'interface. Par exemple: l'Odyssée: Trail of Tears (recherche la page pour elle). La langue dans le rejet est toujours le même (marquage gras ce qu'ils citent pour votre usage):

  

« ... utilise des images d'écran standard iPhone / iPod de manière non standard, ce qui pourrait la confusion des utilisateurs. Modification du comportement des graphiques standards iPhone, Actions , et des images, ou simuler des défaillances de ces graphiques, des actions ou des images est une violation de l'accord de programme pour développeurs iPhone qui nécessite des applications de se conformer aux directives d'interface utilisateur « .

En outre, si vous voulez vraiment cette fonctionnalité, demandez-vous: « Pourquoi? ». Si c'est que vous, vous, comme ça, alors je sauter vraiment. La plupart des utilisateurs seraient désorientés par ce comportement et ne fait l'utiliser parce que ils ne savent pas que c'était une option d'utiliser . Apple a passé les 3 dernières années iphoneos de formation aux utilisateurs comment utiliser leurs éléments OS et l'interface. La dernière chose que vous, en tant que programmeur ou concepteur, voulez faire est de passer du temps à essayer de former un utilisateur sur la façon d'utiliser votre application. Ils enlèveront généralement votre application à partir de leur appareil et de passer à une autre application similaire au lieu de se forcer à apprendre votre chemin de faire les choses.

Juste mon .02 $

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top