Comportement étrange avec Autolayout
Grosse incompréhension sur un nouveau sujet que j'ai commencé avec Swift et Autolayout.
Je pense que le problème vient surtout de ce deuxième.
J'ai 3 vues que j'ai placé côte à côtes au centre de ma vue principale dans un vue principale avec storyboard. J'y ai ajouté les contraintes pour que ces trois vues s'équilibrent sur la largeur des différents iPhone. Jusque là tout va bien.
Lors l'affichage, je veux que ces vues s'affichent ailleurs. Je déplace la vue en utilisant une méthode de ce type :
self.littleView1.origin.y += self.littleView1.size.height*2.0
Là ça commence déjà à être bizarre, car tout va bien si je met dans une méthode
viewDidLayoutSubviews()
Mais pas si je le met dans
viewWillAppear
Ok. Je comprends pas vraiment pourquoi. Et c'est là que j'ai besoin de votre aide pour comprendre pourquoi, une fois affiché et déplacé et que tout va bien, je modifie quelque chose dans une de ces vues :
self.littleViewImage.image = UIImage(named: "image")
Eh bien, il me replace mes éléments comme lors du premier affichage (avant déplacement des objets)
Avec une image, mais c'est pareil avec le texte d'un Label !?
Réponses
Donc forcément même si tu essayes de changer la frame toi même par code vu que tu as mis des contraintes ces dernières vont repositionner tes vues au bon endroit juste après.
Quand on utilise les contraintes on ne dois plus affecter les frames à la main puisque de toute façon il va les affecter pour nous donc même si on les change il va les écraser.
Si tu veux positionner tes vues autre part il suffit de modifier tes contraintes par code plutôt que modifier ta frame.
Merci pour cette précision.
Mais pour déplacer une vue, ça me semble très compliqué d'ajouter des contraintes. Se plus ça mélange des contraintes par code alors qu'il y en a dans le Storyboard.
Je pourrais aussi passer par des transformation du type
Quel est le moyen le plus adapté pour transformer un objet existant dans le Storyboard ?
que tu changes l'origine de ta vue ou la contrainte, ça change pas grand chose... En tous cas, c'est mieux de modifier sa contrainte
Mais il faudrait que tu nous décrives réellement ce que tu souhaites faire pour pouvoir répondre correctement.
PArce que là , tu nous dit :
=> je définie des contraintes dans le storyboard
=> lors de l'affichage, je veux modifier leur position
Donc y a un pb : soit tes contraintes storyboard servent à rien, soit tu ne nous dit pas tout...
J'étais parti en positionnant mes vues dans le Storyboard comme je les veux après l'animation.
Avant que la vue s'affiche je déplace les vues comme je les veux au départ.
J'ai travaillé à l'envers en pensant que c'était plus simple pour bien positionner mes vues, vu qu'au départ, elles sont toutes au même endroit.
J'espère que c'est plus clair ainsi
Il faut définir le jeu de contraintes au départ et le jeu de contraintes souhaitées à l'arrivée, puis animer le changement de contraintes au lieu d'animer un changement de position en dur dans le code.
Oui, je vais supprimer mes contraintes dans IB et refaire le tout par le code. ça m'évitera tout ce bor... que j'ajoute à mesure et qui me font perdre le contrôle.
C'est quand même compliqué ce Autolayout
Moi je ferais plutôt le contraire, mais c'est une affaire de goût.
Je me ferais 2 XIB pour créer mes deux layouts. L'intérêt est de pouvoir vérifier visuellement si les jeux de contraintes sont OK.
La mise au point par code me paraà®t plus fastidieuse.
Une fois la mise au point effectuée, il est facile de reproduire les contraintes voulues par code (et supprimer ou modifier les contraintes du premier jeu).
2 XIB ?
ça m'intéresse, mais je comprends pas là ...
Les transform me semblent une bonne idée !
Si j'ai bien compris l'idée de jp, il ne s'agit pas d'utiliser deux XIB dans le programme, mais plutôt de créer un "XIB brouillon" pour tester graphiquement le rendu de ton interface, après l'animation. Et d'affiner l'aspect (position/taille) des objets en les déplaçant à la souris, plutôt qu'en ajustant les paramètres avec des lignes de code. Quand le résultat est bon, tu n'as plus qu'à lire les contraintes du "XIB brouillon" et les reproduire en code à appliquer sur le XIB d'origine. Et virer le "XIB brouillon", ne servant plus à rien.
C'est carrément l'horreur. Pitié monsieur Simplification, tu peux aller faire un tour chez les ingénieurs d'XCode ?
Oui certes au début c'est un pli à prendre il faut comprendre le concept... mais une fois qu'on a compris, c'est assez simple, et surtout une fois qu'on a bien appris à utiliser Xcode correctement avec on a toutes les billes pour ajouter toutes les contraintes en un clic, facilement rajouter des contraintes exactement où on veut et faire exactement ce qu'on veut.
Le concept en lui-même est plutôt simple, c'est le même concept que par exemple pour la mécanique et la RDM quand on calcule les degrés de liberté d'un système, on indique ce qui doit être figé et ce qui peut être élastique et le système se charge de garantir qu'à tout moment ces contraintes sont satisfaites, de sorte que même si y'a des vues qui changent de taille (changement d'orientation de ton iPhone, etc), les contraintes sont ré-appliquées en permanence pour s'assurer que ce que tu as demandé comme contraintes est toujours satisfait et que tu ne te trouves pas dans un état incohérent avec les contraintes que tu as voulu imposer.
Quand tu mets des contraintes, tu dis clairement "je veux que tu me garantisses, à tout moment, que cette contrainte est satisfaite". Donc c'est pas pour changer la frame après coup, car si tu changes la frame, ça va faire que la contrainte ne sera plus satisfaite et donc le moteur de contraintes va repasser par là pour faire ce que tu lui as demandé, à savoir s'assurer que la contrainte que tu lui as demandé d'assurer soit satisfaite. Mais c'est normal, c'est toi qui lui a demandé ça en mettant une contrainte.
Une contrainte c'est pas juste un état initial, c'est un état constamment fixé.
Je n'aime pas les contraintes. Je ne suis pas un numéro, mais un homme dragon libre.
Plus sérieusement, le principe est intéressant, c'est juste que Xcode n'est pas très ergonomique sur ce plan là .
Attention, en fait il semble que transform et auto-layout ne fassent pas bon ménage !
http://stackoverflow.com/a/14105757/1670830
Exemple des joies d'autolayout (je suis évidemment ironique) :
- sélectionner une contrainte dans le xib en cliquant sur l'objet !
- ça ne marche pas
- aller cherche la contrainte dans la liste des contraintes pas hyper pratique
Bon, le concept commence à s'éclaircir.
Et j'apprends qu'il est possible de faire des IBOutlets sur des contraintes !
Je vais laisser un minimum de contraintes pour pouvoir bouger mes view sans entraver les contraintes.
Je vais voir ensuite comment passer d'un état à l'autre, d'après ce que je comprends à présent, sans toucher au frame...
La première fois que j'ai tenté d'utiliser l'outil de fabrication automatique de contraintes, cela a fonctionné très bien.. Parfait sur iPhone 6, iPhone 5 et iPad. Bon début..
Ensuite j'ai passé le simulateur en mode iPhone 4S et .. paf .. cris et insultes de la part d'XCode. Mauvais début, en fait ..
J'ai fini par comprendre que Xcode avais ajouté tout seul, comme un grand, une contrainte verticale, à partir du bas de l'écran, incompatible avec les dimensions de l'écran d'un 4S. J'avais pourtant réglé le compilateur pour générer du code iOS7, donc compatible iPhone 4.
En fait dans ton cas, il faut placer tes vues comme dans l'image 1 (ttes les unes sur les autres) et définir les contraintes dans l'interface.
Ensuite, tu définies des IBOutlets vers ces contraintes et quand ta vue s'affiche, tu modifies leur valeurs par code et en faisant un appel à une méthode qui va bien (Ali la connait par coeur), les modifications de valeurs vont se faire en mode animation.