mise en page automatique - rendre la hauteur de vue par rapport à la moitié de la hauteur de vue

136

se sont récemment lancés dans la mise en œuvre automatique et je suis coincé sur ce qui semble être un exemple de problème vraiment trivial. Je pense que je veux m'asseoir en haut de l'écran et occuper la moitié de la hauteur de l'écran. Simple avant la mise en page automatique - fixez-le simplement en place et dites-lui de s'étendre verticalement lorsque la super-vue est redimensionnée.

Maintenant, je ne peux pas pour la vie de moi voir comment faire. Voici ce que j'obtiens lorsque j'essaye de configurer ceci:

blues de mise en page automatique

La contrainte d'espace du bas est définie sur "égale 284", ce qui est absolu et absolument inutile pour moi lorsque je passe à la disposition iPhone4, car elle garde 284 points d'espace en bas de l'écran et réduit la vue pour ne plus être la moitié de la taille de l'écran. Et il n'y a aucun moyen de définir cette contrainte pour qu'elle corresponde à une fraction de la hauteur d'une autre vue.

Après avoir lutté pendant un certain temps, la seule façon pour moi de le faire serait d'introduire une autre vue sous cette vue, d'épingler leurs hauteurs de manière égale, de les asseoir au-dessus et en dessous de l'autre, puis de définir la deuxième vue (du bas) pour qu'elle soit invisible. .. ce qui semble un peu moche!

Est-ce que je rate quelque chose d'évident? ..

Infliger
la source
1
Je ne pense pas que ce soit moche, mais une astuce intelligente pour obtenir ce que vous voulez en utilisant IB. J'ai fait cela, et lorsque vous utilisez des noms d'élément appropriés, vous pouvez clarifier ce qui se passe. Vous pouvez même avoir un troisième élément sur une position différente, ou des centres, changer de taille en fonction de ces deux sous-vues.
Jelle

Réponses:

167

Ceci est désormais possible dans IB à partir de [au moins] Xcode 5.1.1. Bien qu'il m'ait fallu du temps pour comprendre que c'est en fait super simple:

Commencez par créer une contrainte d'alignement du haut de base (vous devrez également définir des contraintes de bas, de gauche et de droite, comme d'habitude). Sélectionnez ensuite la contrainte et accédez à l' inspecteur d' attributs :

Démonstration des étapes ci-dessus

Ensuite, vous pouvez ajuster le multiplicateur. Si vous le souhaitez, 50% de la super vue, laissez-le 1, car il est aligné par le centre du super. C'est également un excellent moyen de créer des vues qui sont également d'autres pourcentages (comme 25% de super vue)

Démonstration de la deuxième étape ci-dessus

Firo
la source
nice :) Je pense que ce message devrait être marqué comme réponse acceptée :) Les développeurs iOS préfèrent souvent la solution Interface Builder plutôt que la solution de type code
hqt
@hqt, merci. Je pense que lorsque la réponse acceptée a été écrite, cette méthode n'était pas disponible. Parfois, les demandeurs ne revoient pas les anciennes questions ou ne se soucient pas de changer la réponse acceptée. Mais en fin de compte, je suis juste là pour aider, heureux que cela ait été le cas!
Firo
3
Je suis un peu confus. J'ai essayé cela, mais cela centre simplement la vue sur la vue supervisée, cela n'ajuste pas la hauteur de la vue.
Dean
@Dean, vous devez vous assurer que ce First Itemn'est View.Toppas le cas View.Center Y. Sinon, oui, cela ne fera que le centrer. Vous devrez également vous assurer que les autres contraintes sont correctement définies pour gérer les autres arêtes de la vue.
Firo
1
View.Top est égal à Superview.Le multiplicateur 1 du centre Y vous donne aucune hauteur Cette réponse est incomplète. Tout ce que vous avez à faire est de penser à ce que vous dites et vous pouvez voir que cela vous donne une ligne à travers le centre! Je modifierais cette réponse pour clarifier les autres contraintes dont vous parlez.
smileBot
184

Solution de storyboard où vous pouvez définir le rapport exact entre toutes les vues:

Définir la contrainte d'égalité de hauteur

Maintenant:

Modifier le multiplicateur de la contrainte

PROFIT!!!

Résultat

PS Notez également que cette méthode fonctionne avec des vues sur différents niveaux d'imbrication et (évidemment) applicable pour la largeur

PPS parfois, il peut être utile «d'inverser le premier et le deuxième élément» de la contrainte ou de définir un multiplicateur inverse (par exemple 2 au lieu de 0,5) (mais ces méthodes ne sont pas utiles si vous ne comprenez pas comment les vues sont liées entre elles).

Fyodor Volchyok
la source
1
L'étape 2 ne semble pas fonctionner pour moi. Je ne peux rien sélectionner dans le panneau à part basculer «Contrainte à la marge». J'essaie de définir la largeur d'un UIImageView dans un UITableViewCell à 50% de la vue du contenu.
DrMickeyLauer
2
MISE À JOUR: De toute évidence, le générateur d'interface ne permet pas à la vue de contenu d'être la cible explicite de toute contrainte de mise en page automatique. Je dois insérer une sous-vue factice en tant qu'enfant de la vue de contenu pour que cela fonctionne.
DrMickeyLauer
1
Ça marche pour moi. Vous devez sélectionner les deux vues dans la liste et non l'écran du constructeur. pour les pourcentages, divisez la vue la plus petite par la vue la plus grande pour obtenir la valeur du multiplicateur. Exemple vue plus petite 25, vue plus grande 135 - 25/135 = 0,185. Définissez-le comme valeur multiplicatrice pour obtenir une vue qui, à x1 et x2 = 25, mais évolue avec plus de 6 et 6 plus, etc.
latenitecoder
1
Cela a fonctionné pour moi, mais veuillez noter que je devais également ajouter trois contraintes qui définissaient les contraintes de marge de la sous-vue à 0. Merci
raddevus
Cela devrait être la réponse acceptée. J'essaye d'abord la réponse acceptée. Cela n'a pas fonctionné puis j'ai fait défiler vers le bas et j'ai vu cette réponse et cela a fonctionné. Merci!
Mihir Oza
31

Après un peu plus de temps, j'ai proposé ce qui suit.

Je le note comme une réponse mais ce n'est pas très satisfaisant, car cela suppose que vous ne pouvez pas réellement le faire dans Interface Builder, mais la contrainte correcte peut être ajoutée dans le code par la suite comme:

- (void) viewWillAppear:(BOOL)animated
{

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:upperview
                                                                 attribute:NSLayoutAttributeHeight 
                                                                 relatedBy:0 
                                                                    toItem:self.view
                                                                 attribute:NSLayoutAttributeHeight
                                                                multiplier:.5 
                                                                  constant:0];
    [self.view addConstraint:constraint];

}

Fondamentalement, il définit un multiplicateur de 0,5 par rapport à la hauteur de self.view, agissant sur upperview. J'ai dû définir la priorité de la contrainte d'espace vertical inférieur dans IB à moins de 1000 pour éviter également un tas de messages d'exécution sur la rupture des contraintes.

Donc, si quelqu'un peut montrer comment faire cela dans Interface Builder, cela répondrait mieux à ma question, sinon je suppose que c'est aussi bon que possible (pour le moment) ???

Infliger
la source
3
Je pense que c'est aussi bon que maintenant. Ce serait bien si Apple nous donnait accès à la valeur du multiplicateur dans IB, afin que cela puisse être défini ainsi que la constante.
rdelmar
3
Pour tous ceux qui recherchent cette réponse, Xcode 5.1 vous permet désormais de définir le multiplicateur via Interface Builder. Je suis maintenant en mesure de configurer des vues qui font la moitié de la hauteur de leur supervision via IB.
Mark Krenek
9

Légèrement plus facile et plus simple que la méthode que la réponse de Fyodor Volchyok. -Maintenez le bouton de contrôle enfoncé et cliquez sur la sous-vue. -Tout en maintenant le bouton de commande enfoncé, faites glisser le curseur sur la vue supervisée puis cliquez sur la vue supervisée. -Sélectionnez "Rapport hauteur / largeur".

entrez la description de l'image ici

-Puis cliquez sur l'inspecteur de taille. -Ensuite, double-cliquez sur la contrainte. entrez la description de l'image ici

-Assurez-vous que "hauteur" est sélectionné pour les deux éléments. entrez la description de l'image ici

-Ensuite, changez le "Multiplicateur" à 0,5 pour la moitié de l'écran, ou quelle que soit la fraction de la vue que vous désirez. entrez la description de l'image ici

user444333222
la source
Approche simple et rapide! Merci mate
Abdullah Saeed
7

Il y a aussi une autre possibilité dans le code au cas où vous auriez 2 vues qui devraient toutes deux avoir la même hauteur: réglez simplement la hauteur de view2 à la hauteur de view1 (l'astuce ici n'est pas de définir explicitement la hauteur de view1).

    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[topLayoutGuide]-0-[_view1]-0-[_view2(==_view1)]-0-[bottomLayoutGuide]"
                            options:0
                            metrics:nil
                              views:viewsDict]];
cerveau
la source
Je ne savais pas que vous pouviez référencer d'autres vues pour des largeurs / hauteurs comme ça. C'est la réponse la plus claire IMO si vous êtes déjà dans le langage du format visuel.
loeschg
L'exemple @brainray est également expliqué sur developer.apple.com ici
alecs.popa
0

Version rapide de la réponse de Mete:

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.



    upperView.translatesAutoresizingMaskIntoConstraints = false


    var constraint = NSLayoutConstraint(item: upperView,
                                        attribute: NSLayoutAttribute.top,
                                        relatedBy: NSLayoutRelation.equal,
                                        toItem: self.view,
                                        attribute: NSLayoutAttribute.top,
                                        multiplier: 1,
                                        constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.height,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.height,
                                    multiplier: 0.5,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.leading,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.leading,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.trailing,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.trailing,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


}
user444333222
la source