2013-05-24 34 views
6

Giả sử tôi có hai Chế độ xem văn bản. Trong chế độ chân dung, tôi muốn những hình dưới đây & khác Trong chế độ phong cảnh, tôi muốn những phải cạnh nhauHai chế độ xem, bên dưới một chế độ xem khác dọc theo chiều dọc và cạnh nhau theo chiều ngang sử dụng các ràng buộc bố cục

Có thể làm điều đó bằng những hạn chế bố trí trong kịch bản sử dụng autolayout? Nếu có, thì làm cách nào? Nếu không, thì điều gì sẽ là giải pháp tốt hơn để đạt được điều này.

iOS6 là phiên bản mục tiêu của tôi

Trả lời

8

Đây là cách bạn có thể thực hiện nó bằng mã.

Về cơ bản bạn cần phải:

a) cấu hình thích hợp NSLayoutConstraint s cho định hướng được đưa ra trong updateViewConstraints trong UIViewController của bạn.

b) gọi [self.view setNeedsUpdateConstraints] khi giao diện quay.

Dưới đây là triển khai ViewController và danh mục trên UIView với các phương pháp trợ giúp.

@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 

Đặt này trong 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 

Đây là 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

Tôi gặp phải lỗi này: "Không hiển thị @interface cho 'UIView' khai báo lựa chọn 'constrainSubview: usingEdgeInsets:'" – Homam

+0

@Homam bạn có thêm danh mục ràng buộc trên UIView không? –

+0

Để kiểm tra tôi đã tạo dự án mẫu với ứng dụng SingleView. Đã sao chép toàn bộ mã của bạn sang ViewController. – Homam

2

Theo tôi cách tốt nhất để xem cách bố trí viewController trong nhiều hơn một định hướng là tạo ra vài quan điểm cho mỗi hướng. Here tôi đã tìm thấy điều này:

"Khi bạn thêm bộ điều khiển chế độ xem vào bảng phân cảnh, nó sẽ có chế độ xem: xem chế độ xem vùng chứa và chế độ xem ngang. Thêm các nút, nhiều lượt xem, nhãn hoặc bất kỳ thứ gì vào chế độ xem dọc và ngang khi cần cho ứng dụng của bạn. Sau đó, khi định hướng thay đổi ẩn một chế độ xem và hiển thị chế độ xem khác. "

0

Bạn có thể đạt được hành vi như vậy bằng cách sử dụng giao diện Builder chỉ. Bạn cần thiết lập một số ràng buộc với các ưu tiên khác nhau.

Xem câu trả lời chi tiết hơn về chủ đề here. Ngoài ra còn có một screencast và một liên kết đến một ứng dụng ví dụ tôi đã tạo ra.

Các vấn đề liên quan