75 votes

Est-il possible d'ajouter une contrainte entre une vue et le guide de disposition supérieur dans un fichier xib?

Dans iOS 7, nous pouvons maintenant ajouter une contrainte entre la vue et le haut de page, qui je pense est très utile pour résoudre la barre d'état de décalage problème dans iOS7(surtout quand il n'y a pas de barre de navigation dans la vue).

Dans un storyboard fichier, je peux ajouter ce type de contraintes facilement. Il suffit de maintenir la touche contrôle enfoncée, puis faites glisser la vue vers le conteneur, il va montrer le "Haut de l'Espace pour couronner le Guide de Présentation de l'option".

enter image description here

Mais quand je fais la même opération dans un fichier xib, cette option disparaît.

enter image description here

Donc, est-il possible d'ajouter ce genre de contraintes dans les fichiers xib? Ou dois-je les ajouter avec le code?

78voto

Neeraj Khede Points 344

Vous devriez vous référer à l'exemple suivant, cela vous aidera certainement à résoudre votre problème. Je viens de http://developer.apple.com .

 [button setTranslatesAutoresizingMaskIntoConstraints: NO];
id topGuide = myViewController.topLayoutGuide;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings (button, topGuide);

[myViewController.view addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat: @"V:[topGuide]-20-[button]"
    options: 0
    metrics: nil
    views: viewsDictionary]
];
 

14voto

ananfang Points 107

Voici ma solution alternative.

Recherchez un UIView en tant que pivot, définissez sa contrainte de disposition supérieure sur un espace vertical fixe sur le dessus du conteneur.

Faites glisser cette contrainte de mise en forme en tant que commande IBOutlet, telle que

 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *topLayoutConstraint;
 

Enfin, il suffit de remplacer la méthode viewWillLayoutSubviews de UIViewController comme suit

 - (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    self.topLayoutConstraint.constant = [self.topLayoutGuide length] + YOUR_TOP_CONSTRSINT;
}
 

La contrainte supérieure de toutes les autres vues est basée sur cette vue pivot, tout est fait :)

6voto

Cao Huu Loc Points 429

Jusqu'à maintenant, même à l'aide de XCode 6, je ne peut pas aligner les contrôles haut de page en page .xib fichiers. Au lieu de cela, je suis en utilisant un autre moyen.

Tout d'abord, sur l'interface builder, je continue à aligner les contrôles à la frontière supérieure de la viewcontroler de vue.

Ensuite, dans la méthode viewDidLoad, j'ai remplacer certaines contraintes de manière à ce qu'ils vont aligner en haut de page en page au lieu de l'écran principal:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSArray *constraints = self.view.constraints;
    for (NSLayoutConstraint *constraint in constraints) {
        if ( (constraint.firstItem == self.view) && (constraint.firstAttribute == NSLayoutAttributeTop) ) {
            NSLayoutConstraint *newConstraint = [self constraint:constraint replaceFirstItemBy:self.topLayoutGuide attribute:NSLayoutAttributeBottom];
            [self.view removeConstraint:constraint];
            [self.view addConstraint:newConstraint];
        } else if ( (constraint.secondItem == self.view) && (constraint.secondAttribute == NSLayoutAttributeTop) ) {
            NSLayoutConstraint *newConstraint = [self constraint:constraint replaceSecondItemBy:self.topLayoutGuide attribute:NSLayoutAttributeBottom];
            [self.view removeConstraint:constraint];
            [self.view addConstraint:newConstraint];
        }
    }
}

- (NSLayoutConstraint*)constraint:(NSLayoutConstraint*)constraint replaceFirstItemBy:(id)newItem attribute:(NSLayoutAttribute)newAttribute {
    UILayoutPriority priority = constraint.priority;
    NSLayoutRelation relation = constraint.relation;
    id secondItem = constraint.secondItem;
    NSLayoutAttribute secondAttribute = constraint.secondAttribute;
    CGFloat multiplier = constraint.multiplier;
    CGFloat constant = constraint.constant;

    NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:newItem attribute:newAttribute relatedBy:relation toItem:secondItem attribute:secondAttribute multiplier:multiplier constant:constant];
    newConstraint.priority = priority;
    return newConstraint;
}

- (NSLayoutConstraint*)constraint:(NSLayoutConstraint*)constraint replaceSecondItemBy:(id)newItem attribute:(NSLayoutAttribute)newAttribute {
    UILayoutPriority priority = constraint.priority;
    id firstItem = constraint.firstItem;
    NSLayoutAttribute firstAttribute = constraint.firstAttribute;
    NSLayoutRelation relation = constraint.relation;
    CGFloat multiplier = constraint.multiplier;
    CGFloat constant = constraint.constant;

    NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:firstItem attribute:firstAttribute relatedBy:relation toItem:newItem attribute:newAttribute multiplier:multiplier constant:constant];
    newConstraint.priority = priority;
    return newConstraint;
}

Pense que ce n'est pas la meilleure façon pour que l'on remplace les objets qui nous définir dans interface builder. Mais il est peut-être une autre façon que nous pouvons penser.

5voto

David Pettigrew Points 134

Je pense que la raison pour laquelle ils ne figurent pas dans la XIB est qu’il n’ya aucune connaissance de la hiérarchie du contrôleur de vue dans cette situation, alors que dans un story-board, IB peut indiquer où se trouvent les guides de la hiérarchie du contrôleur de vue dans laquelle se trouve la vue. Par exemple, s'il est contenu dans un UINavigationController, il peut déterminer que le guide de présentation supérieur se trouve sous la barre d'outils de navigation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X