2013-05-24 4 views
6

Angenommen, ich habe zwei Textansichten. Im Portrait-Modus, möchte ich diese untereinander & Im Landscape-Modus, möchte ich diese Seite an Seite seinZwei Ansichten, eine unter der anderen im Hoch- und Querformat unter Verwendung von Layoutbeschränkungen

Ist es möglich, dass die Verwendung von Layoutbeschränkungen in Storyboard zu tun mit automatischem Layout? Wenn ja, wie? Wenn nicht, was wäre dann die andere bessere Lösung, um dies zu erreichen.

iOS6 ist meine Zielversion

Antwort

8

So könnten Sie im Code verfahren.

Grundsätzlich müssen Sie:

a) in updateViewConstraints in Ihrem UIViewController die entsprechenden NSLayoutConstraint s für die gegebene Orientierung konfigurieren.

b) Rufen Sie [self.view setNeedsUpdateConstraints] an, wenn sich die Schnittstelle dreht.

Unten ist eine ViewController-Implementierung und eine Kategorie in UIView mit Hilfsmethoden.

@interface ConstraintsViewController() 

@property (nonatomic, weak) IBOutlet UIView *upperOrLeftView, *lowerOrRightView; 

@end 


@implementation ConstraintsViewController 

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; 
    [self.view setNeedsUpdateConstraints]; 
} 

-(void)updateViewConstraints { 
    [super updateViewConstraints]; 

    [self.view removeConstraintsRelatingToItems:@[self.upperOrLeftView,self.lowerOrRightView]]; 

    if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 
     [self.view constrainSubview:self.upperOrLeftView usingEdgeInsets:UIEdgeInsetsMake(0, 0, -1, 0)]; 
     [self.view constrainSubview:self.lowerOrRightView usingEdgeInsets:UIEdgeInsetsMake(-1, 0, 0, 0)]; 
     [self.view constrainSubviewsTopToBottom:@[self.upperOrLeftView, self.lowerOrRightView]]; 
    } 
    else { 
     [self.view constrainSubview:self.upperOrLeftView usingEdgeInsets:UIEdgeInsetsMake(0, 0, 0, -1)]; 
     [self.view constrainSubview:self.lowerOrRightView usingEdgeInsets:UIEdgeInsetsMake(0, -1, 0, 0)]; 
     [self.view constrainSubviewsLeftToRight:@[self.upperOrLeftView, self.lowerOrRightView]]; 
    } 
} 

@end 

Setzen Sie dieses in UIView + Constraints.h

@interface UIView (Constraints) 

-(void)removeConstraintsRelatingToItems:(NSArray*)items; 

-(void)constrainSubview:(UIView*)subview usingEdgeInsets:(UIEdgeInsets)insets; 

-(void)constrainSubviewsLeftToRight:(NSArray*)subviews; 

-(void)constrainSubviewsTopToBottom:(NSArray*)subviews; 

@end 

Dies ist UIView + Constraints.m

@implementation UIView (Constraints) 

-(void)removeConstraintsRelatingToItems:(NSArray *)items { 
    for(NSLayoutConstraint *constraint in self.constraints) { 
     if([items containsObject:constraint.firstItem] || [items containsObject:constraint.secondItem]) { 
      [self removeConstraint:constraint]; 
     } 
    } 
} 

/** Set up constraints to flow the subviews from top to bottom and with equal heights */ 
-(void)constrainSubviewsTopToBottom:(NSArray*)subviews { 
    if(subviews.count > 1) { 
     UIView *anchorView = subviews[0]; 
     for(int i = 1; i < subviews.count; i++) { 
      UIView *view = subviews[i]; 
      NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:anchorView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]; 
      NSLayoutConstraint *edgesConstraint = [NSLayoutConstraint constraintWithItem:anchorView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]; 
      [self addConstraints:@[heightConstraint, edgesConstraint]]; 
      anchorView = view; 
     } 
    } 
} 

/** Set up constraints to flow the subviews from left to right and with equal widths */ 
-(void)constrainSubviewsLeftToRight:(NSArray*)subviews { 
    if(subviews.count > 1) { 
     UIView *anchorView = subviews[0]; 
     for(int i = 1; i < subviews.count; i++) { 
      UIView *view = subviews[i]; 
      NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:anchorView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]; 
      NSLayoutConstraint *edgesConstraint = [NSLayoutConstraint constraintWithItem:anchorView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]; 
      [self addConstraints:@[widthConstraint, edgesConstraint]]; 
      anchorView = view; 
     } 
    } 
} 

/** 
Set up constraints to anchor the various edges of the subview to it's superview (this view) using the provided insets. 
Any inset set to < 0.0 means that edge is ignored; 
*/ 
-(void)constrainSubview:(UIView*)subview usingEdgeInsets:(UIEdgeInsets)insets { 
    if(insets.top >= 0.0) { 
     [self addConstraint:[NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:insets.top]]; 
    } 

    if(insets.right >= 0.0) { 
     [self addConstraint:[NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:-insets.right]]; 
    } 

    if(insets.bottom >= 0.0) { 
     [self addConstraint:[NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-insets.bottom]]; 
    } 

    if(insets.left >= 0.0) { 
     [self addConstraint:[NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:insets.left]]; 
    } 
} 

@end 
+0

Ich erhalte diese Fehlermeldung: „Kein sichtbarer @interface für 'UIView spricht der Wähler‚constrainSubview: usingEdgeInsets:‘“ – Homam

+0

@Homam Sie die Einschränkungen Kategorie auf UIView hinzugefügt haben? –

+0

Zum Testen habe ich ein Beispielprojekt mit SingleView-Anwendung erstellt. Kopierte den gesamten Code in ViewController. – Homam

2

Meiner Meinung nach der beste Weg, Viewcontroller Ansichten in mehr als einer Orientierung Layout ist einige Ansichten für jede Orientierung zu schaffen.

„Wenn Sie einen View-Controller es mit Blick kommt zum Storyboard hinzufügen Rufen Sie, dass der Behälter view In zwei Ansichten auf den Behälter Ansicht: Here Ich habe dies gefunden... Eine Portraitansicht und eine Landschaftsansicht Set die Größe der Hoch- und Queransicht mit Hilfe des Größeninspektors anpassen Fügen Sie dem Hoch- und Querformat entsprechend Ihrer Anwendung Schaltflächen, weitere Ansichten, Beschriftungen usw. hinzu, und ändern Sie dann die Ausrichtung, während Sie die eine Ansicht ausblenden und die andere anzeigen. "

0

Sie ein solches Verhalten nur mit Interface Builder erreichen könnte. Sie müssen einige Einschränkungen mit unterschiedlichen Prioritäten einrichten.

Siehe meine detailliertere Antwort zum Thema here. Außerdem gibt es einen Screencast und einen Link zu einer Beispielanwendung, die ich erstellt habe.

Verwandte Themen