試想這樣的一個需求場合,一個button靠右顯示,并且距離superView的頂部和右邊間距分別為10和5。如下圖所示:
要實現這樣的需求,如果不用自動布局技術,那么我們能想到的就是老老實實的使用絕對布局的坐標計算來實現了,假如這個button寬高都是100,父視圖的寬是300,那么這個button的坐標就是:(300-100-5,10)。但要是父視圖的寬度變了,我們還得重新計算一遍。頗為麻煩。
幸好我們有自動布局技術。要實現這樣的需求還是相對比較簡單的。
既然我們要實現這樣的需求,而且這個需求其實也是具有普遍性的,那么我們直接封裝下好了。我們給UIView添加兩個擴展屬性:horizontalAlignment和verticalAlignment。兩個屬性都是枚舉。
typedef NS_ENUM(NSInteger, UIViewVerticalAlignment) { UIViewVerticalAlignmentFill = 0, UIViewVerticalAlignmentCenter = 1, UIViewVerticalAlignmentTop = 2, UIViewVerticalAlignmentBottom = 3 };typedef NS_ENUM(NSInteger, UIViewHorizontalAlignment) { UIViewHorizontalAlignmentFill = 0, UIViewHorizontalAlignmentCenter = 1, UIViewHorizontalAlignmentLeft = 2, UIViewHorizontalAlignmentRight = 3};@PRoperty (nonatomic,assign)UIViewHorizontalAlignment horizontalAlignment;@property (nonatomic,assign)UIViewVerticalAlignment verticalAlignment;
實現的思路如下:
我下面以水平停靠舉例,對于水平停靠有四種情況,首先就是不停靠完全的填充,也就是我們把該subview的寬度跟superview的寬度綁定到一起。第二種情況是左邊停靠,依次還有居中停靠和右邊停靠。
對于非填充停靠,在寬度方面肯定不能直接綁定到superview的寬度了,只能使用UIView的擴展屬性size的寬度了。
現在以上述場景的實現為例,就是水平方向右邊停靠。那么我們只要把subview的NSLayoutAttributeRight跟superview的NSLayoutAttributeRight對齊就好了。代碼如下:
[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeRight multiplier:1.0f constant:-margin.right]];
對于左邊停靠和居中停靠無非就是對齊的屬性不一樣。對于垂直停靠來說也是這樣。
完整的停靠代碼如下:
UIEdgeInsets margin=self.margin; switch (self.verticalAlignment) { case UIViewVerticalAlignmentFill: { NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top-[view]-bottom-|" options:0 metrics:@{ @"top" : @(margin.top),@"bottom":@(margin.bottom)} views:@{ @"view" : self}]; [self.superview addConstraints:constraints]; } break; case UIViewVerticalAlignmentBottom: { [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-margin.bottom]]; } break; case UIViewVerticalAlignmentCenter: { [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0]]; } break; case UIViewVerticalAlignmentTop: { [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeTop multiplier:1.0f constant:margin.top]]; } break; default: break; } switch (self.horizontalAlignment) { case UIViewHorizontalAlignmentFill:{ NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-left-[view]-right-|" options:0 metrics:@{ @"left" : @(margin.left),@"right":@(margin.right)} views:@{ @"view" : self}];//添加寬度的約束 [self.superview addConstraints:constraints]; } break; case UIViewHorizontalAlignmentCenter:{ [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0]]; } break; case UIViewHorizontalAlignmentLeft:{ [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeLeft multiplier:1.0f constant:margin.left]]; } break; case UIViewHorizontalAlignmentRight:{ [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeRight multiplier:1.0f constant:-margin.right]]; } break; default: break; }
對于停靠,我們前面寫的UIStackPanel和UIGridView勢必也要支持的。因此我也修改了下原來的代碼。
然后對于圖中 的那個button的代碼就是如下:
UIButton *btn=[[UIButton alloc] initWithSize:CGSizeMake(100, 100)]; [btn setBackgroundColor:[UIColor blueColor]]; btn.isBindSizeToSuperView=YES; [btn setTitle:@"button1" forState:UIControlStateNormal]; btn.horizontalAlignment=UIViewHorizontalAlignmentRight; btn.verticalAlignment=UIViewVerticalAlignmentTop; btn.margin=UIEdgeInsetsMake(10, 0, 0, 5); [self.view addSubview:btn];
至此這個系列的博客完結!
新聞熱點
疑難解答