Modal view controller sans storyboard

Bonjour !


 


Dans mon app, j'ai fait le choix de ne pas utiliser storyboard. Bref. Maintenant, je voudrais afficher un view controller (modalVC) au-dessus d'un autre (mainVC), en modal. Je souhaiterais que modalVC ne remplisse pas tout l'écran et qu'on voie dans le fond mainVC, mais en flou. Bref, quelque chose de très classique.


 


J'ai essayé la chose suivante (sur iPad simulator):



UIViewController * mainVC = self.mainVC ;

mainVC.modalPresentationStyle = UIModalPresentationPopover ;

[self.mainVC presentViewController:self.modalVC animated:YES completion:nil] ;


- Le modalVC apparaà®t bien, en "push over", depuis le bas (j'aimerais idéalement qu'il "splashe"), mais il occupe tout l'écran.


 


- J'ai pourtant bien indiqué dans le xib définissant modalVC : mode "center" et non "scale to fill".


 


 

Réponses

  • Faut pas redéfinir la taille de ta modal dans son view controller ?


  • J'ai défini la taille du modal dans son xib. As-tu une idée plus précise sur comment "redéfinir la taille de ta modal dans son view controller" ?


  • dans le viewdidload (ou viewdidappear ou un endroit comme ca), tu fais un reframe de ta view


  • FKDEVFKDEV Membre
    octobre 2014 modifié #5
    Le modal presentation style que tu utilises est réservé aux popovers, et après tes lignes de code tu dois configurer ton popover controller. C'est expliqué ici :https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationController_class/index.html.


    Si tu veux une modal sans popover il faut utiliser un autre style.

    Les anciens sytles ont une taille predefinie. Le plus courant est UIModalPresentationFormSheet.


    Il y a un style custom dans iOS7 Qui devrait pouvoir te permettre de choisir ta taille (a confirmer).

    Il y a un nouveau style iOS8 only qui permet de voir les vues derriere la modal.
  • colas_colas_ Membre
    octobre 2014 modifié #6

    @FKDEV J'avoue avoir un peu choisi au pif pour le `modalPresentationStyle` . Même en choisissant le mode `UIModalPresentationFormSheet`, la fenêtre modale remplit tout l'écran


     


    ça marche !


    En fait dans un premier temps je sentais le modalPresentationStyle pour le modalVC alors que c'est pour mainVC qu'il fallait le faire.


     


    Effectivement, la taille est fixée pour UIModalPresentationFormSheet. 


     


    Le custom de iOS8 n'a pas l'air de marcher (ça prend tout l'écran).


     


    Il y a évidemment encore l'erreur 



    Presenting view controllers on detached view controllers is discouraged <MyCBDExploreExerciseAndCommentariesMainVC: 0x7c450c80>.

    Je prendrai du temps pour chercher un pod. Si je trouve un truc bien, je le posterai.


     


    C'est pas encore ça, mais ça avance ! Merci !


  • ah oui effectivement je n'avais pas ton erreur.


    au passage : mainVC et modalVC ne sont pas des noms très significatifs. C'est mieux que VC1 et VC2 mais pas de beaucoup.


     


    Le warning vient du fait que ton mainVC qui présente la modale n'est pas relié par une chaà®ne de controller au root controller de la main window.  (window.rootViewController que tu affectes en général dans l'app delegate).


     


    En général cela arrive quand tu ajoutes la vue gérée par ton controller à  une vue parente sans relier les deux controllers.



    [self.window.rootViewController.view addSubview:self.mainVC.view]

    Pour corriger tu peux ajouter ton mainVC en tant que child controller de ton rootViewController.


     


    Cela se fait de manière transparente quand tu utilises des éléments de navigation standard (type UINavigationController ou UITabController).

  • Merci !


    Pour l'instant, je pense à  implémenter mon propre mécanisme. ça doit pas être très compliqué, il faut que je comprenne le flou (à  voir car je target ios6) et comment désactiver les actions sur le mainVC.


    J'ai choisi ces noms juste pour le forum !
  • FKDEVFKDEV Membre
    octobre 2014 modifié #9

    Regarde les sources de MBProgressHUD par exemple (pour la partie modale et désactivation du reste).


    Pour le flou, il y a des frameworks qui imitent le flou de iOS 7. Je ne sais pas s'ils sont compatibles iOS 6.


  • Merci de ton aide FKDEV.


     


    Pour l'instant, j'ai un petite classe qui tourne. La voilà  :


     


    .h :



    #import <Foundation/Foundation.h>

    @interface CBDModalViewManager : NSObject


    #pragma mark - Parameters
    @property (nonatomic, assign, readwrite) CGFloat opacity ;
    @property (nonatomic, assign, readwrite) NSTimeInterval durationWhenAppears ;
    @property (nonatomic, assign, readwrite) NSTimeInterval durationWhenDisappears ;


    #pragma mark - Init

    - (instancetype)initWithPresentedViewController:(UIViewController *)presentedVC
    overPresenterViewController:(UIViewController *)presenterVC ;


    #pragma mark - Core methods

    - (void)present ;
    - (void)dismiss ;


    @end

    .m :




    #import "CBDModalViewManager.h"









    //
    //
    /**************************************/
    #pragma mark - Constants
    /**************************************/

    static CGFloat const kDefaultOpacity = 0.8 ;
    static NSTimeInterval const kDefaultDuration = 0.3 ;










    @interface CBDModalViewManager ()

    /*
    Parameters
    */
    @property (nonatomic, weak, readwrite) UIViewController * presentedVC ;
    @property (nonatomic, weak, readwrite) UIViewController * presenterVC ;


    /*
    Components
    */
    @property (nonatomic, strong, readwrite) UIView * handlerForPresentedView ;


    /*
    Convenience properties
    */
    @property (nonatomic, readonly) UIView * presentedView ;
    @property (nonatomic, readonly) UIView * presenterView ;


    @end















    @implementation CBDModalViewManager



    /**************************************/
    #pragma mark - Init
    /**************************************/


    - (instancetype)initWithPresentedViewController:(UIViewController *)presentedVC
    overPresenterViewController:(UIViewController *)presenterVC
    {
    self = [super init] ;

    if (self)
    {
    /*
    Parameters
    */
    _presentedVC = presentedVC;
    _presenterVC = presenterVC ;
    _opacity = kDefaultOpacity ;
    _durationWhenAppears = kDefaultDuration ;
    _durationWhenDisappears = kDefaultDuration ;


    /*
    We load the view of the VCs !
    */
    [presentedVC view] ;
    [presenterVC view] ;
    }

    return self ;
    }


    - (void)createTheHandlerView
    {
    UIView * result ;

    /*
    The frame
    */
    CGRect frame ;
    CGSize size = CGSizeApplyAffineTransform(self.presenterView.frame.size,
    self.presenterView.transform) ;

    frame.size = CGSizeMake(ABS(size.width),
    ABS(size.height)) ;
    frame.origin = CGPointZero ;

    /*
    Creating the view
    */
    result = [[UIView alloc] initWithFrame:frame] ;


    /*
    Configuring it
    */
    result.backgroundColor = [UIColor colorWithRed:0
    green:0
    blue:0
    alpha:self.opacity] ;

    /*
    Placing the presented view inside
    */
    self.presentedView.center = result.center ;
    [result addSubview:self.presentedView] ;


    /*
    Assigning
    */
    _handlerForPresentedView = result ;
    }




    //
    //
    /**************************************/
    #pragma mark - Convenience methods
    /**************************************/

    - (UIView *)presentedView
    {
    return self.presentedVC.view ;
    }

    - (UIView *)presenterView
    {
    return self.presenterVC.view ;
    }


    //
    //
    /**************************************/
    #pragma mark - Core methods
    /**************************************/


    - (void)present
    {
    /*
    First, we create the handler
    */
    [self createTheHandlerView] ;


    self.presentedView.alpha = 0 ;
    self.presentedView.transform = CGAffineTransformMakeScale(0, 0) ;

    [UIView animateWithDuration:self.durationWhenAppears/3
    delay:0
    options:UIViewAnimationOptionCurveEaseInOut
    animations:^{
    [self.presenterView addSubview:self.handlerForPresentedView] ;
    }
    completion:^(BOOL finished) {
    [UIView animateWithDuration:self.durationWhenAppears*2/3
    delay:0
    options:UIViewAnimationOptionCurveEaseIn
    animations:^{
    self.presentedView.alpha = 1 ;
    self.presentedView.transform = CGAffineTransformIdentity ; }
    completion:nil] ;
    }];
    }


    - (void)dismiss
    {
    [UIView animateWithDuration:self.durationWhenAppears/3
    delay:0
    options:UIViewAnimationOptionCurveEaseInOut
    animations:^{
    self.handlerForPresentedView.alpha = 0 ;
    self.presentedView.transform = CGAffineTransformMakeScale(0, 0) ;
    }
    completion:^(BOOL finished) {
    self.presentedView.transform = CGAffineTransformIdentity ;
    [self.presentedView removeFromSuperview] ;
    [self.handlerForPresentedView removeFromSuperview] ;
    self.handlerForPresentedView = nil ;
    }] ;
    }

    @end


    Si certains veulent participer au projet, je crée un github : https://github.com/colasjojo/CBDModalViewManager


     


    Le vrai problème (mais bon...) de mon angle d'attaque c'est qu'il crée du code spaghetti : pour se dismisser, la vue modale doit connaà®tre le ModalManager. Et, grosso modo, le ModalManager est en général possédé par la "mainVC" (la presenterVC).


     


    L'animation est un peu pourrie pour l'instant mais améliorer ça ne me demandera pas beaucoup de travail !


     


     


    Merci aux contributeurs de forum.cocoacafé !!!


Connectez-vous ou Inscrivez-vous pour répondre.