2013-08-29 45 views
0

我認爲這是自動佈局的問題。ios AutoLayout問題的靈活寬度?

我創建了一個視圖,並在其中創建了一些子視圖。

內容視圖包含子視圖,子視圖將所有內容放在一行中。

我想我沒有做錯什麼,但內容視圖的框架總是不正確的。

這樣的:

2013-08-29 14:13:34.688 AutoLayoutBugTest[4658:c07] pV_content.frame {{0, 208}, {319, 44}} 

內容視圖的寬度是319,但不是320,更改在viewDidLoad中功能 'CNT' PARAM,框架可更差。

這樣的代碼:

@interface ViewController() 
@property (nonatomic, strong) UIView   *pV_content; 
@property (nonatomic, strong) NSMutableArray *Arr_views; 
@end 

@implementation ViewController 

- (void)removeConstraintForCustomView:(UIView *)customView 
          fromView:(UIView *)superView 
{ 
    NSMutableArray *pArr_constraint = [NSMutableArray array]; 
    for (NSLayoutConstraint *constraint in superView.constraints) { 
     if ([constraint.firstItem isEqual:customView]) { 
      [pArr_constraint addObject:constraint]; 
     } 
    } 
    [superView removeConstraints:pArr_constraint]; 
    pArr_constraint = nil; 
} 

- (void)constraintCustomView:(UIView *)customView 
      matchWidthOfView:(UIView *)superView 
        withHeight:(CGFloat)height 
{ 
    [self removeConstraintForCustomView:customView fromView:superView]; 

    customView.translatesAutoresizingMaskIntoConstraints = NO; 
    NSLayoutConstraint *constraint_y = [NSLayoutConstraint constraintWithItem:customView 
                     attribute:NSLayoutAttributeCenterY 
                     relatedBy:NSLayoutRelationEqual 
                     toItem:superView 
                     attribute:NSLayoutAttributeCenterY 
                    multiplier:1.f 
                     constant:0.f]; 
    [superView addConstraint:constraint_y]; 

    NSLayoutConstraint *constraint_height = [NSLayoutConstraint constraintWithItem:customView 
                     attribute:NSLayoutAttributeHeight 
                     relatedBy:NSLayoutRelationEqual 
                      toItem:superView 
                     attribute:NSLayoutAttributeHeight 
                     multiplier:0.f 
                      constant:height]; 
    [superView addConstraint:constraint_height]; 

    NSLayoutConstraint *constraint_left = [NSLayoutConstraint constraintWithItem:customView 
                     attribute:NSLayoutAttributeLeft 
                     relatedBy:NSLayoutRelationEqual 
                      toItem:superView 
                     attribute:NSLayoutAttributeLeft 
                     multiplier:1.f 
                     constant:0.f]; 
    [superView addConstraint:constraint_left]; 

    NSLayoutConstraint *constraint_width = [NSLayoutConstraint constraintWithItem:customView 
                     attribute:NSLayoutAttributeWidth 
                     relatedBy:NSLayoutRelationEqual 
                      toItem:superView 
                     attribute:NSLayoutAttributeWidth 
                     multiplier:1.f 
                     constant:0.f]; 
    [superView addConstraint:constraint_width]; 
} 

- (void)constraintCustomView:(UIView *)customView 
    matchWidthPercentOfView:(UIView *)superView 
        boxCount:(int)boxCount 
        boxIndex:(int)boxIndex 
{ 
    [self removeConstraintForCustomView:customView fromView:superView]; 

    customView.translatesAutoresizingMaskIntoConstraints = NO; 
    NSLayoutConstraint *constraint_top = [NSLayoutConstraint constraintWithItem:customView 
                     attribute:NSLayoutAttributeTop 
                     relatedBy:NSLayoutRelationEqual 
                     toItem:superView 
                     attribute:NSLayoutAttributeTop 
                    multiplier:1.f 
                     constant:customView.frame.origin.y]; 
    [superView addConstraint:constraint_top]; 
    constraint_top.priority = UILayoutPriorityFittingSizeLevel; 

    NSLayoutConstraint *constraint_height = [NSLayoutConstraint constraintWithItem:customView 
                     attribute:NSLayoutAttributeHeight 
                     relatedBy:NSLayoutRelationEqual 
                      toItem:superView 
                     attribute:NSLayoutAttributeHeight 
                     multiplier:0.f 
                      constant:customView.frame.size.height]; 
    [superView addConstraint:constraint_height]; 
    constraint_height.priority = UILayoutPriorityFittingSizeLevel; 

    if (boxCount == 1) { 
     NSLayoutConstraint *constraint_percent_x = [NSLayoutConstraint constraintWithItem:customView 
                       attribute:NSLayoutAttributeCenterX 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:superView 
                       attribute:NSLayoutAttributeCenterX 
                       multiplier:1.f 
                       constant:0.f]; 
     [superView addConstraint:constraint_percent_x]; 
     constraint_percent_x.priority = UILayoutPriorityFittingSizeLevel; 

     NSLayoutConstraint *constraint_width = [NSLayoutConstraint constraintWithItem:customView 
                      attribute:NSLayoutAttributeWidth 
                      relatedBy:NSLayoutRelationEqual 
                       toItem:superView 
                      attribute:NSLayoutAttributeWidth 
                      multiplier:1.f 
                      constant:-4.f]; 
     [superView addConstraint:constraint_width]; 
     constraint_width.priority = UILayoutPriorityFittingSizeLevel; 
    } 
    else { 
     if (boxIndex == 0) { 
      NSLayoutConstraint *constraint_left = [NSLayoutConstraint constraintWithItem:customView 
                       attribute:NSLayoutAttributeLeft 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:superView 
                       attribute:NSLayoutAttributeLeft 
                       multiplier:1.f 
                       constant:0.f]; 
      [superView addConstraint:constraint_left]; 
      constraint_left.priority = UILayoutPriorityFittingSizeLevel; 

      NSLayoutConstraint *constraint_width = [NSLayoutConstraint constraintWithItem:customView 
                       attribute:NSLayoutAttributeWidth 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:superView 
                       attribute:NSLayoutAttributeWidth 
                       multiplier:(2.f/(CGFloat)(2 * boxCount + 1)) 
                       constant:-2.f]; 
      [superView addConstraint:constraint_width]; 
      constraint_width.priority = UILayoutPriorityFittingSizeLevel; 
     } 
     else if (boxIndex == boxCount - 1) { 
      NSLayoutConstraint *constraint_right = [NSLayoutConstraint constraintWithItem:customView 
                       attribute:NSLayoutAttributeRight 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:superView 
                       attribute:NSLayoutAttributeRight 
                       multiplier:1.f 
                       constant:0.f]; 
      [superView addConstraint:constraint_right]; 
      constraint_right.priority = UILayoutPriorityFittingSizeLevel; 

      NSLayoutConstraint *constraint_width = [NSLayoutConstraint constraintWithItem:customView 
                       attribute:NSLayoutAttributeWidth 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:superView 
                       attribute:NSLayoutAttributeWidth 
                       multiplier:(2.f/(CGFloat)(2 * boxCount + 1)) 
                       constant:-2.f]; 
      [superView addConstraint:constraint_width]; 
      constraint_width.priority = UILayoutPriorityFittingSizeLevel; 
     } 
     else { 
      NSLayoutConstraint *constraint_percent_x = [NSLayoutConstraint constraintWithItem:customView 
                        attribute:NSLayoutAttributeCenterX 
                        relatedBy:NSLayoutRelationEqual 
                         toItem:superView 
                        attribute:NSLayoutAttributeCenterX 
                        multiplier:(((CGFloat)(2 * boxIndex + 1))/(CGFloat)boxCount) 
                        constant:0.f]; 
      [superView addConstraint:constraint_percent_x]; 
      constraint_percent_x.priority = UILayoutPriorityFittingSizeLevel; 

      NSLayoutConstraint *constraint_width = [NSLayoutConstraint constraintWithItem:customView 
                       attribute:NSLayoutAttributeWidth 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:superView 
                       attribute:NSLayoutAttributeWidth 
                       multiplier:(2.f/(CGFloat)(2 * boxCount + 1)) 
                       constant:-2.f]; 
      [superView addConstraint:constraint_width]; 
      constraint_width.priority = UILayoutPriorityFittingSizeLevel; 
     } 
    } 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    self.view.backgroundColor = [UIColor whiteColor]; 

    self.pV_content = [[UIView alloc] initWithFrame:CGRectMake(0.f, 
                   0.f, 
                   self.view.frame.size.width, 
                   44.f)]; 
    self.pV_content.backgroundColor = [UIColor lightGrayColor]; 
    [self.view addSubview:self.pV_content]; 
    [self constraintCustomView:self.pV_content 
         matchWidthOfView:self.view 
          withHeight:44.f]; 

    int cnt = 5; 

    for (int i = 0; i < cnt; i++) { 
     UIView *pV_sub = [[UIView alloc] initWithFrame:CGRectMake(0.f, 
                    5.f, 
                    30.f, 
                    35.f)]; 
     pV_sub.backgroundColor = [UIColor redColor]; 
     [self.pV_content addSubview:pV_sub]; 
     [self constraintCustomView:pV_sub 
        matchWidthPercentOfView:self.pV_content 
            boxCount:cnt 
            boxIndex:i]; 
    } 
} 

- (void)viewDidLayoutSubviews 
{ 
    [super viewDidLayoutSubviews]; 
    NSLog(@"pV_content.frame %@", NSStringFromCGRect(self.pV_content.frame)); 
} 

- (BOOL)shouldAutorotate 
{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskAll; 
} 

@end 

回答

0

從引導:

約束的形式是 「view1.attr1 view2.attr2 *乘數+常數」。如果您希望表達的約束沒有第二個視圖和屬性,請使用nil和NSLayoutAttributeNotAnAttribute。

和二級:嘗試使用

constraintsWithVisualFormat:options:metrics:views: 

例如,如果你有一個觀點testView:

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[testView]|" options:0 metrics:0 views:@{@"testView":self.testView}]]; 

在constraintsWithVisualFormat方法,你可以設置優先級和變種,如:@「H:| - (0 @ 100) - [testView(100)] - (0 @ 100) - |」。這個testView有優先權,因爲優先級參數沒有設置,但是從左右尺寸到superview的約束優先級爲100,而你的視圖testView沒有改變自己的幀。 你可以像這樣設置格式:[testView(50,100)]在你的代碼中意思是:「testView widht可以是50分或者是100. Read this guide