[Résolu] iPad présentation différente portrait/paysage avec les size classes

Alf1996Alf1996 Membre
novembre 2017 modifié dans API UIKit #1

Bonjour, 


 


J'ai un problème exactement identique à  ce sujet sur SO. Par contre, la solution proposée est en swift... et comme je suis toujours sur Objective C (et oui, je suis flemmarde !!!). Quelqu'un aurait il la gentillesse de me faire une traduction ? Je n'ai pas trouvé de Google Traduction swift-->objective C !!!


Merci d'avance.


 


Mots clés:

Réponses

  • Je ne sais pas quelle version tu veux exactement, mais de ce que j'ai compris :

    Dériver UIView, appelons là  CustomView qui sera ta titleView d'un UINavigationItem.

    Réécrire intrinsicContentSize pour qu'il retourne la taille de ton choix.

     


  • LeChatNoirLeChatNoir Membre, Modérateur

    Alf,


     


    Tu devrais t'y mettre. C'est sûr, ça fait perdre du temps mais les liaisons swift/obj-C sont relativement bien faites et simples.


    Du coup, pour tout nouvel écran, force toi à  le faire en swift.


     


    Après, pour ton soucis, c'est strange... Tu as une custom view dans ta navigation bar ? Ou juste un title et un right button ?


     




    Bonjour, 


     


    J'ai un problème exactement identique à  ce sujet sur SO. Par contre, la solution proposée est en swift... et comme je suis toujours sur Objective C (et oui, je suis flemmarde !!!). Quelqu'un aurait il la gentillesse de me faire une traduction ? Je n'ai pas trouvé de Google Traduction swift-->objective C !!!


    Merci d'avance.



  • Joanna CarterJoanna Carter Membre, Modérateur

    Il y a plusieurs problèmes sur cette page SO. C'est exactement quoi ton souci ?


  • Merci pour vos réponses, et désolée pour la réponse tardive, j'étais au simulateur, puis un réseau capricieux... !


     




    Je ne sais pas quelle version tu veux exactement, mais de ce que j'ai compris :

    Dériver UIView, appelons là  CustomView qui sera ta titleView d'un UINavigationItem.

    Réécrire intrinsicContentSize pour qu'il retourne la taille de ton choix.

     




     


     




    Alf,


     


    Tu devrais t'y mettre. C'est sûr, ça fait perdre du temps mais les liaisons swift/obj-C sont relativement bien faites et simples.


    Du coup, pour tout nouvel écran, force toi à  le faire en swift.


     


    Après, pour ton soucis, c'est strange... Tu as une custom view dans ta navigation bar ? Ou juste un title et un right button ?




     


    Promis, je vais essayer d'y réfléchir... mais comme tu le dis, je vais perdre un peu de temps, et pour l'instant, il me manque déjà  beaucoup de temps !!!


    Rien de bien compliqué, un titre et deux boutons "annuler" et "valider".


     




    Il y a plusieurs problèmes sur cette page SO. C'est exactement quoi ton souci ?




     


    Et bien il n'y a plus de navbar en haut (c'est juste grisé) et je n'ai plus ni le titre ni les 2 boutons. Du coup, je suis coincée sur la view, impossible de valider ni d'annuler.


     


    Je précise que cela n'arrive que sur une de mes vues, et comme par hasard c'est une vue que je viens de modifier pour avoir un design différent en portrait et en paysage sur iPad. Or, comme depuis les size class, il n'est plus possible de différencier l'iPad en portrait et en paysage (tout est "regular"), j'ai suivi une réponse d'un problème similaire sur SO, et j'ai fait ceci :




    - (UITraitCollection *)traitCollection {
    UITraitCollection *verticalRegular = [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassRegular];

    if (self.view.bounds.size.width < self.view.bounds.size.height) {
    // wCompact, hRegular
    return [UITraitCollection traitCollectionWithTraitsFromCollections:
    @[;[UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact],
    verticalRegular]];
    } else {
    // wRegular, hRegular
    return [UITraitCollection traitCollectionWithTraitsFromCollections:
    @[;[UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular],
    verticalRegular]];
    }
    }




    - (void)orientationChanged:(NSNotification *)notification{
    [_myFirstCollectionView reloadData];
    [_mySecondCollectionView reloadData];
    }


    Le problème peut-il venir de là  ?


     


     


  • Bonsoir,


     


    Je reviens sur mon problème... J'ai simplement viré la méthode "(UITraitCollection *)traitCollection" citée ci dessus, et çà  refonctionne... Donc du coup, je me demande maintenant comment faire pour avoir des dispositions différentes en portrait et en paysage sur iPad avec les size class... sans pour autant faire disparaitre ma navBar ? Une idée ?


  • Je relance car je suis toujours bloquée...


    Vous faites comment pour avoir un visuel différent sur iPad en portrait et en paysage ? Car lorsque j'utilise la méthode citée plus haut, je n'ai plus ma NavBar. J'ai loupé un truc ?


  • On utilise les SizeClass maintenant. Tu peux les gérer sur IB plus facilement que ce que tu avais l'air de faire.




  • On utilise les SizeClass maintenant. Tu peux les gérer sur IB plus facilement que ce que tu avais l'air de faire.




     


     


    Bah justement, c'est çà  mon problème. J'utilise les size class aussi. Le problème, c'est que pour l'iPad, qu'il soit en portrait ou en paysage, c'est du "regular". Et je souhaiterais faire un design différent en portrait et en paysage...


    J'ai trouvé des trucs sur SO, mais c'est du swift...  :'(  Et ce que j'ai essayé en Objective C ne fonctionne pas (disparition de la NavBar). Je ne comprends pas...



  •  


    Donc du coup, je me demande maintenant comment faire pour avoir des dispositions différentes en portrait et en paysage sur iPad avec les size class... sans pour autant faire disparaitre ma navBar ? Une idée ?




    C'est facile à  faire avec Storyboard. On peut définir une interface en mode " regular " pour toutes les orientations, ou en " regular portrait "  et " regular paysage ". Bon, je présume que cela ne t'aide pas beaucoup. 


     


    Sinon, tu peux tester les dimensions de la vue au moment de la construction de l'interface, pour différencier les modes portrait et paysage.



  • C'est facile à  faire avec Storyboard. On peut définir une interface en mode " regular " pour toutes les orientations, ou en " regular portrait "  et " regular paysage ". Bon, je présume que cela ne t'aide pas beaucoup. 


     




     


     


    ??


     


    Je dois vraiment être trop nulle !! 



  • ??


     


    Je dois vraiment être trop nulle !! 




    Si mes souvenirs sont bon, tu n'utilises pas Storyboard, et fait tout en code, non ?

  • Si j'utilise Storyboard, c'est swift que je n'utilise pas encore, je suis encore en Obj-C. Par contre je vais devoir me faire violence pour passer à  Swift à  ma prochaine application (ou pour les prochaines classes), car je trouve de moins en moins de réponses sur els forums en Objective C.



  • Si j'utilise Storyboard, c'est swift que je n'utilise pas encore, je suis encore en Obj-C. Par contre je vais devoir me faire violence pour passer à  Swift à  ma prochaine application (ou pour les prochaines classes), car je trouve de moins en moins de réponses sur els forums en Objective C.




    Problème résolu, alors ?

  • Tu devrais essayer de suivre la documentation : https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/Size-ClassSpecificLayout.html


     


    L'interface à  changé depuis iOS10 et xcode8 mais le concept reste identique.




  • Problème résolu, alors ?




     


    Bah non !


     


     




    Tu devrais essayer de suivre la documentation : https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/Size-ClassSpecificLayout.html


     


    L'interface à  changé depuis iOS10 et xcode8 mais le concept reste identique.




     


    Merci Magiic. Je connais ce document, mais malheureusement, çà  ne résout pas mon problème. Ou alors il y a un truc que j'ai mal interprété.


    Dites moi si je me trompe :


    - iPhone portrait : w compact - h regular


    - iPhone paysage : w regular - h compact


    - iPad : w regular - h regular sans distinction de portrait / paysage... et c'est là  qu'est mon problème.


     


    Merci à  tous pour votre aide.

  • DrakenDraken Membre
    novembre 2017 modifié #17


    C'est facile à  faire avec Storyboard. On peut définir une interface en mode " regular " pour toutes les orientations, ou en " regular portrait "  et " regular paysage ".




    Bon j'ai dus rêver. J'étais persuadé d'avoir réussi à  le faire sous Storyboard avec Xcode 8. Je cherche vainement à  reproduire la manipulation avec Xcode 9 depuis 19 heures, sans y arriver. Et c'est bien dommage. Désolé, Alf.


     


    La seule solution que je vois pour ton problème c'est de réaliser la vue à  géométrie variable par code (avec un drawrect), et de tester la largeur/hauteur pour savoir si c'est du portrait ou du paysage.



  • Bon j'ai dus rêver. J'étais persuadé d'avoir réussi à  le faire sous Storyboard avec Xcode 8. Je cherche vainement à  reproduire la manipulation avec Xcode 9 depuis 19 heures, sans y arriver. Et c'est bien dommage. Désolé, Alf.


     


    La seule solution que je vois pour ton problème c'est de réaliser la vue à  géométrie variable par code (avec un drawrect), et de tester la largeur/hauteur pour savoir si c'est du portrait ou du paysage.




     


    Merci d'avoir essayé si longtemps Draken !


     


    Le problème est que la vue est assez complexe, alors c'était plus simple pour moi de la faire avec Storyboard...


     


    Je vais renommer le sujet, car le problème est un peu différent de ce que j'avais au début !



  • Merci d'avoir essayé si longtemps Draken !


     




    C'est surtout pour moi que j'ai cherché. J'ai horreur de raconter des choses fausses et encore plus d'être persuadé d'avoir réalisé quelque chose que .. finalement .. bah non.. :'(


     


    J'ai réalisé des tas d'exercices sur les contraintes au début de l'année, pendant le MOOC sur le développement iOS du prof Kordon. A force de créer les mêmes applications en 3 versions :


    - contraintes sous Storyboard


    - construction programmatique des interfaces par code pur


    - programmation des contraintes Storyboard dans le code (la technique la plus performante, mais horrible à  mettre en oeuvre)


    je me suis mêlé les pinceaux

  • Voila, je reviens à  la charge sur mon problème. Je n'ai malheureusement pas pu avancer ces derniers temps car j'avais d'autres trucs à  régler... J'ai créé un petit projet test pour voir si j'arrivais à  m'en sortir avec des vues très simples.


     


    Voici ce que j'aimerais faire (2 captures d'écran). J'ai essayé de faire un "vary for traits", mais toujours pareil vu que l'iPad est Regular/Regular quelle que soit son orientation. 


     


    Les deux images correspondent à  des contraintes différentes... 


     


    Une petite idée ? ou dois-je me résoudre à  créer ma vue par code ? Si c'est çà , comment va se passer la rotation, tout va se redessiner à  chaque fois qu'on tourne le device ? Et enfin, est-ce possible d'avoir toutes les vues en storyboard, sauf une par code..


     


    Merci pour votre aide.  o:)


     


     


  • Joanna CarterJoanna Carter Membre, Modérateur

    J'ai utilisé les contraintes pour positionner les sous-vues et j'ai change les constantes sur la rotation. Je t'ai envoyé un MP avec un exemple confidentiel




  • J'ai utilisé les contraintes pour positionner les sous-vues et j'ai change les constantes sur la rotation. Je t'ai envoyé un MP avec un exemple confidentiel




    Ah oui, je vois. Je n'y aurais jamais pensé. Tu as dus définir des outlets sur les contraintes Storyboard pour les modifier dans le code. Et détecter le changement d'orientation avec le je-sais-plus-quoi coordinator. Puis tester la taille de l'écran pour déterminer l'orientation et ensuite ajuster les contraintes via les outlets. Non ?

  • Joanna CarterJoanna Carter Membre, Modérateur
    novembre 2017 modifié #23
    Si :)

    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
    {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];

    if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
    {
    self.aircraftEditorViewLeadingConstraint.constant = 256.0;
    }
    else
    {
    self.aircraftEditorViewLeadingConstraint.constant = 0.0;
    }
    }

    - (void)viewWillAppear:(BOOL)animated
    {
    if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
    {
    self.aircraftEditorViewLeadingConstraint.constant = 256.0;
    }
    else
    {
    self.aircraftEditorViewLeadingConstraint.constant = 0.0;
    }

    [super viewWillAppear:animated];
    }
  • Merci infiniment Joanna, et désolée de ne pas t'avoir répondu plus tôt !


     


    J'avais déjà  utilisé des Outlet sur des contraintes, mais dans ce cas précis, je n'y avais pas pensé... La difficulté est juste de définir les bonnes contraintes, mais çà  devrait être possible. Je me mets au boulot dès ce soir, et je vous tiens au courant !


     


    Encore merci !  :D   :D   :D


  • Alf1996Alf1996 Membre
    novembre 2017 modifié #25

    Voila les news...


     


    çà  fonctionne super ! Il me reste juste à  faire quelques ajustements sur les contraintes pour peaufiner le visuel final, mais la rotation se passe bien. Par contre, j'ai utilisé viewWillTransitionToSize plutôt que willAnimateRotationToInterfaceOrientation, afin de pouvoir ajouter un "block de completion" qui s'execute à  la fin de la rotation. Voici le principe final :



    -(void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
    UIInterfaceOrientation toInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
    // Mise à  jour des contraintes pour le format Paysage
    } else {
    // Mise à  jour des contraintes pour le format Portrait
    }
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {
    // reloadData des différentes CollectionViews et TableViews pour leur permettre d'adapter leur contenu à  leur nouvelle taille
    }];

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    }


    Encore un grand merci pour ton aide précieuse Joanna  :D   :D   :D  !!!


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