2010-06-04 6 views
0

que je fais un modal de recouvrement partiel dans mon application avec le code de « Semi-modales (transparent) Dialogs sur l'iPhone » à ramin.firoozye.com. Ce faisant, le bouton qui appelle le modal est toujours visible et cliquable. Je vais cacher ce bouton lorsque le modal apparaitra, mais je veux être sûr que si l'utilisateur clique très vite deux fois, un nouveau modal n'apparaît pas pour chaque clic. Quel est le meilleur moyen de vérifier que le modal n'existe pas déjà en l'appelant depuis le bouton click?iPhone: Créez un UIView à partir de plusieurs clics

Vous pouvez download the test project here. Pour ceux qui n'ont pas Xcode, les fonctions correspondantes sont ci-dessous:

J'appelle le modal sur le bouton, cliquez avec ceci:

- (IBAction)displayModal:(id)sender { 
    ModalViewController *modalController = [[ModalViewController alloc] initWithNibName:@"ModalViewController" bundle:nil]; 
    modalController.view.frame = CGRectOffset(modalController.view.frame, 0, 230); 
    [self showModal:modalController.view]; 
} 

Ensuite, utilisez cette fonction pour animer le modal personnalisé dans la vue actuelle :

- (void)showModal:(UIView*) modalView { 
    UIWindow* mainWindow = (((TestAppDelegate*) [UIApplication sharedApplication].delegate).window); 

    CGPoint middleCenter = modalView.center; 
    CGSize offSize = [UIScreen mainScreen].bounds.size; 
    CGPoint offScreenCenter = CGPointMake(offSize.width/2.0, offSize.height * 1.5); 
    modalView.center = offScreenCenter; // we start off-screen 
    [mainWindow addSubview:modalView]; 

    // Show it with a transition effect 
    [UIView beginAnimations:nil context:nil]; 
    [UIView setAnimationDuration:0.4]; // animation duration in seconds 
    modalView.center = middleCenter; 
    [UIView commitAnimations]; 
} 

Alors je rejette le modal sur le bouton, cliquez avec ceci:

- (IBAction)dismissModal:(id)sender { 
    [self hideModal:self.view]; 
} 

Et puis utiliser ces fonctions pour animer le hors-champ modal et se nettoyer:

- (void)hideModal:(UIView*) modalView { 
    CGSize offSize = [UIScreen mainScreen].bounds.size; 
    CGPoint offScreenCenter = CGPointMake(offSize.width/2.0, offSize.height * 1.5); 
    [UIView beginAnimations:nil context:modalView]; 
    [UIView setAnimationDuration:0.7]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationDidStopSelector:@selector(hideModalEnded:finished:context:)]; 
    modalView.center = offScreenCenter; 
    [UIView commitAnimations]; 
} 

- (void)hideModalEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { 
    UIView* modalView = (UIView *)context; 
    [modalView removeFromSuperview]; 
    [self release]; 
} 

Toute aide est grandement appréciée!

Répondre

0

Je ne voulais vraiment pas avoir recours à une variable globale pour garder une trace du modal déjà existant, j'ai donc décidé d'utiliser la notification.

Je mets cela dans mon contrôleur de navigation où j'appelle le modal:

- (void)viewDidLoad { 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notShowingModal) name:@"ModalDidClose" object:nil]; 
    [super viewDidLoad]; 
} 

- (void)notShowingModal { 
    isShowingModal = NO; 
} 

Ensuite, je mets cela dans le contrôleur modal où le modal est rejeté:

- (void)viewDidDisappear:(BOOL)animated { 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ModalDidClose" object:nil]; 
} 

Je pourrais probablement le faire avec l'AppDelegate aussi. Si quelqu'un pense que cela, ou n'importe quoi d'autre, serait mieux adapté à cela, faites le moi savoir.

0

Si je comprends bien votre question, vous pouvez simplement faire: Sender.hidden = OUI; la première ligne dans la IBAction

Sinon, vous pourriez avoir une BOOL Ivar dans votre tête comme ceci:

{ 
    BOOL isShowingModal; 
} 

Et mettre dans une instruction if dans displayModal, et mettre isShowingModal YES

Et dans hideModal, réglez-le à NO

+0

Je suppose que je vais devoir mettre mes fonctions de masquage dans la même classe que les fonctions d'affichage afin de maintenir ce conditionnel. Merci pour l'astuce ajoutée sur le fait de cacher le bouton, mais les erreurs Sender.hidden que l'expéditeur est non déclaré. [sender setHidden: YES]; compile, mais déclenche un sélecteur non reconnu envoyé à une erreur d'instance. Des idées? – Cuzog

+0

D'après ce que je peux dire, UIBarButtonItems ne peut pas être caché. Ils ne peuvent être réglés que sur zéro puis réinitialisés. J'ai l'intention de cacher toute la barre de navigation lorsque le modal s'affiche de toute façon, ce qui, heureusement, a une méthode intégrée pour gérer cela. – Cuzog

+0

Ah ... Oui, je me souviens toujours très ennuyé que le compilateur ne vous permette pas d'utiliser la syntaxe de point de propriété sur le type d'id (même quand cela fonctionnerait réellement).Je sais que cela ne va pas aider maintenant, mais pour l'avenir si vous définissez la méthode comme ceci: - (IBAction) doWhatever: (UIBarButtonItem *) expéditeur alors ça va fonctionner très bien. Je pensais que vous utilisiez un UIButton, qui, à ma connaissance, peut être caché. J'espère que vous le gérerez! Une autre méthode (bien que vous en ayez déjà une) soit d'utiliser le modèle délégué et de définir la vue qui a la barre comme délégué du modal. –