UIView 等寬或等高排列

JoeGrayndle 8年前發布 | 5K 次閱讀 UIView iOS開發 移動開發

在 UI 開發中,時不時需要把幾個按鈕或者 UILabel 并排著排列,在以前用坐標系布局時都是靠算,很麻煩還容易出錯,現在 Autolayout 這么方便,能不能使用 Autolayout 完成這個布局工作呢?試試看。

Autolayout 的布局規則是寫 View 與 View 間的相對關系,我們來分析一下,如果要使 3 個 View 在一個容器 View 中均分需要滿足哪些條件。

  1. 最左邊 View 到父 View 一定邊距
  2. 所有 View 寬度相等
  3. 一個 View 到下一個 View 有一定邊距
  4. 最右邊 View 到父 View 一定邊距

如果想要這些 View 在容器中完全均分,上述的邊距都為 0 即可。

按照上面的想法來實踐下,以下代碼中的幾個方法是對 NSLayoutConstraint 實例方法 constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant: 的簡單封裝,字面意思,詳情實現見 UIView+CPYLayout.m

以下方法為 NSArray 的一個擴展,假設我們將所需要布局的 View 放在了一個數組中,并都 addSubview 到了一個容器 View 中。

UIView *container=[[UIView alloc]init];
[self.view addSubview:container];
container.backgroundColor =[UIColor redColor];

[[[[container cpy_alignYToSuperview]cpy_toHeight:100]cpy_leftToSuperview:0]cpy_rightToSuperview:0];

NSMutableArray *arr = [NSMutableArray array];
for (int i = 0; i < 8; i++) {
 UIView *v = [[UIView alloc]init];
 v.backgroundColor = [UIColor blueColor];
[container addSubview:v];
[arr addObject:v];
[v cpy_constraintEqualTo:NSLayoutAttributeWidth toView:v toAttribute:NSLayoutAttributeHeight constant:0];
}

[arr cpy_flexibleWidthWithMargin:10 spacing:10];
@implementationNSArray (cpy_layout)
- (void)cpy_flexibleWidthWithMargin:(CGFloat)marginspacing:(CGFloat)spacing {
 for (NSInteger i = 0; i < self.count;i++) {
 UIView *tmp = self[i];

if(i ==0) {
// 設置第一 View 到父 View 的左邊距
[tmp cpy_leftToSuperView:margin];
 }

 if (tmp == self.lastObject) {
// 最后一個,設置到父 View 右邊距
[tmp cpy_rightToSuperView:margin];
 }
 else {
// 不是最后一個,設置寬度相等和到下一個 View 的間距
 UIView *next = self[i + 1];
[[tmp cpy_constraintEqualTo:NSLayoutAttributeWidth toView:next toAttribute:NSLayoutAttributeWidth constant:0]cpy_rightToLeftToView:nextconstant:spacing];
 }
// 設置居中
 [tmp cpy_alignYToSuperView];
 }
}
@end

效果如下:

也可以不設置容器 View 的寬度或者邊距約束,讓它根據子 View 的布局后的大小自行調整大小,但是這樣的話,就需要設置子 View 到容器的邊距約束,不然沒辦法完成布局。代碼如下:

UIView *container=[[UIView alloc]init];
[self.view addSubview:container];
container.backgroundColor =[UIColor redColor];

// 只設置了居中,沒有設置邊距和寬高約束
[container cpy_centerToSuperview];

NSMutableArray *arr = [NSMutableArray array];
for (int i = 0; i < 8; i++) {
 UIView *v = [[UIView alloc]init];
 v.backgroundColor = [UIColor blueColor];
[container addSubview:v];
[arr addObject:v];

 // 這里設置了寬度,和到父 View 的上下邊距
[[[v cpy_toWidth:20]cpy_topToSuperview:0]cpy_bottomToSuperview:0];
[v cpy_constraintEqualTo:NSLayoutAttributeWidth toView:v toAttribute:NSLayoutAttributeHeight constant:0];
}

// 這里會設置子 View 到父 View 的左右邊距
[arr cpy_flexibleWidthWithMargin:0 spacing:10];

這樣約束條件都滿足了,運行看一下效果:

同理,也可以垂直等高排列:

UIView *container=[[UIView alloc]init];
[self.view addSubview:container];
container.backgroundColor =[UIColor redColor];

[container cpy_centerToSuperview];

NSMutableArray *arr = [NSMutableArray array];
for (int i = 0; i < 8; i++) {
 UIView *v = [[UIView alloc]init];
 v.backgroundColor = [UIColor blueColor];
[container addSubview:v];
[arr addObject:v];

[[[v cpy_toWidth:20]cpy_leftToSuperview:0]cpy_rightToSuperview:0];
[v cpy_constraintEqualTo:NSLayoutAttributeWidth toView:v toAttribute:NSLayoutAttributeHeight constant:0];
}

[arr cpy_flexibleHeightWithMargin:0 spacing:5];

效果如下:

嗯,還不錯 :)

這樣就不用算一大堆坐標,只需要設置幾條約束就可以了,并且這樣如果需要添加或者去掉一個 View 也比較方便。

 

完整 Demo 見: https://github.com/cielpy/CPYFlexibleViewDemo

 

來自:https://imciel.com/2016/08/29/uiview-same-width-autolayout/

 

 本文由用戶 JoeGrayndle 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!