iOS第三方 -训练营:Masonry

Masonry

1 - AutoLayout 并没有直接提供等间隙排列的方法,Masonry 的官方 Demo 中也没有对应的案例。但是我们可以通过一个小技巧来实现这个目的,为此这里为 UIView 添加了一个 Category

// - UIView+Masonry_LJC.h

1 #import <UIKit/UIKit.h>
2 @interface UIView (Masonry_LJC)
3 
4 - (void) distributeSpacingHorizontallyWith:(NSArray*)views;// 横向排列
5 - (void) distributeSpacingVerticallyWith:(NSArray*)views;  // 纵向排列
6 
7 @end

// - UIView+Masonry_LJC.m 

复制代码
 1 #import "UIView+Masonry_LJC.h"
 2 #import "Masonry.h"
 3 @implementation UIView (Masonry_LJC)
 4 
 5 // 横向间隔排列
 6 - (void)distributeSpacingHorizontallyWith:(NSArray*)views{
 7 
 8     NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:0];
 9 
10     for ( int i = 0 ; i < views.count+1 ; ++i ){
11         UIView *v = [UIView new];
12         [self addSubview:v];
13         [spaces addObject:v];
14 
15         [v mas_makeConstraints:^(MASConstraintMaker *make) {
16             make.width.equalTo(v.mas_height);
17         }];
18     }
19 
20     UIView *v0 = spaces[0];
21 
22     [v0 mas_makeConstraints:^(MASConstraintMaker *make) {
23         make.left.equalTo(self.mas_left);
24         make.centerY.equalTo(((UIView*)views[0]).mas_centerY);
25     }];
26 
27     UIView *lastSpace = v0;
28     for ( int i = 0 ; i < views.count; ++i ){
29         UIView *obj = views[i];
30         UIView *space = spaces[i+1];
31 
32         [obj mas_makeConstraints:^(MASConstraintMaker *make) {
33             make.left.equalTo(lastSpace.mas_right);
34         }];
35 
36         [space mas_makeConstraints:^(MASConstraintMaker *make) {
37             make.left.equalTo(obj.mas_right);
38             make.centerY.equalTo(obj.mas_centerY);
39             make.width.equalTo(v0);
40         }];
41 
42         lastSpace = space;
43     }
44 
45     [lastSpace mas_makeConstraints:^(MASConstraintMaker *make) {
46         make.right.equalTo(self.mas_right);
47     }];
48 
49 }
50 
51 // 纵向间隔排列
52 - (void) distributeSpacingVerticallyWith:(NSArray*)views{
53     NSMutableArray *spaces = [NSMutableArray arrayWithCapacity:0];
54 
55     for ( int i = 0 ; i < views.count+1 ; ++i ){
56         UIView *v = [UIView new];
57         [spaces addObject:v];
58         [self addSubview:v];
59 
60         [v mas_makeConstraints:^(MASConstraintMaker *make) {
61             make.width.equalTo(v.mas_height);
62         }];
63     }
64 
65 
66     UIView *v0 = spaces[0];
67 
68     [v0 mas_makeConstraints:^(MASConstraintMaker *make) {
69         make.top.equalTo(self.mas_top);
70         make.centerX.equalTo(((UIView*)views[0]).mas_centerX);
71     }];
72 
73     UIView *lastSpace = v0;
74     for ( int i = 0 ; i < views.count; ++i ){
75         UIView *obj = views[i];
76         UIView *space = spaces[i+1];
77 
78         [obj mas_makeConstraints:^(MASConstraintMaker *make) {
79             make.top.equalTo(lastSpace.mas_bottom);
80         }];
81 
82         [space mas_makeConstraints:^(MASConstraintMaker *make) {
83             make.top.equalTo(obj.mas_bottom);
84             make.centerX.equalTo(obj.mas_centerX);
85             make.height.equalTo(v0);
86         }];
87 
88         lastSpace = space;
89     }
90 
91     [lastSpace mas_makeConstraints:^(MASConstraintMaker *make) {
92         make.bottom.equalTo(self.mas_bottom);
93     }];
94 
95 }
96 
97 @end
复制代码

2 - 代码示例

① 横向或纵向等间隙地排列一组 view

复制代码
 1 #import "ViewController.h"
 2 #import "Masonry.h"
 3 #import "UIView+Masonry_LJC.h"
 4 @implementation ViewController
 5 
 6 - (void)viewDidLoad {
 7     [super viewDidLoad];
 8     self.view.backgroundColor = [UIColor whiteColor];
 9     self.navigationController.navigationBar.hidden = YES;
10 
11     // 5个 UIView
12     UIView *sv11 = [UIView new];
13     UIView *sv12 = [UIView new];
14     UIView *sv13 = [UIView new];
15     UIView *sv21 = [UIView new];
16     UIView *sv31 = [UIView new];
17 
18     // 背景颜色
19     sv11.backgroundColor = [UIColor redColor];
20     sv12.backgroundColor = [UIColor orangeColor];
21     sv13.backgroundColor = [UIColor purpleColor];
22     sv21.backgroundColor = [UIColor blueColor];
23     sv31.backgroundColor = [UIColor blackColor];
24 
25     // 添加
26     [self.view addSubview:sv11];
27     [self.view addSubview:sv12];
28     [self.view addSubview:sv13];
29     [self.view addSubview:sv21];
30     [self.view addSubview:sv31];
31 
32     // 约束
33     [sv11 mas_makeConstraints:^(MASConstraintMaker *make) {
34         make.size.mas_equalTo(CGSizeMake(180, 180));
35     }];
36 
37     [sv12 mas_makeConstraints:^(MASConstraintMaker *make) {
38         make.size.mas_equalTo(CGSizeMake(70, 20));
39     }];
40 
41     [sv13 mas_makeConstraints:^(MASConstraintMaker *make) {
42         make.size.mas_equalTo(CGSizeMake(50, 50));
43     }];
44 
45     [sv21 mas_makeConstraints:^(MASConstraintMaker *make) {
46         make.size.mas_equalTo(CGSizeMake(50, 20));
47     }];
48 
49     [sv31 mas_makeConstraints:^(MASConstraintMaker *make) {
50         make.size.mas_equalTo(CGSizeMake(40, 60));
51     }];
52 
53 //    // 单排横向布局
54 //    [self.view distributeSpacingHorizontallyWith:@[sv11,sv12,sv13,sv21,sv31]];
55     
56     // 单列纵向布局
57     [self.view distributeSpacingVerticallyWith:@[sv11,sv12,sv13,sv21,sv31]];
58 }
59 
60 @end 
复制代码

运行效果:横向布局 | 纵向布局

        

② 横向且纵向等间隙的排列一组 view

复制代码
  1 #import "ViewController.h"
  2 #import "Masonry.h"
  3 #import "UIView+Masonry_LJC.h"
  4 @implementation ViewController
  5 
  6 - (void)viewDidLoad {
  7     [super viewDidLoad];
  8     self.view.backgroundColor = [UIColor whiteColor];
  9     self.navigationController.navigationBar.hidden = YES;
 10 
 11     // 5 个 UIView
 12     UIView *sv11 = [UIView new];
 13     UIView *sv12 = [UIView new];
 14     UIView *sv13 = [UIView new];
 15     UIView *sv14 = [UIView new];
 16     UIView *sv15 = [UIView new];
 17 
 18     UIView *sv21 = [UIView new];
 19     UIView *sv31 = [UIView new];
 20     UIView *sv41 = [UIView new];
 21     UIView *sv51 = [UIView new];
 22     UIView *sv61 = [UIView new];
 23 
 24 
 25     // 背景颜色
 26     sv11.backgroundColor = [UIColor redColor];
 27     sv12.backgroundColor = [UIColor orangeColor];
 28     sv13.backgroundColor = [UIColor purpleColor];
 29     sv14.backgroundColor = [UIColor yellowColor];
 30     sv15.backgroundColor = [UIColor greenColor];
 31 
 32     sv21.backgroundColor = [UIColor blueColor];
 33     sv31.backgroundColor = [UIColor blackColor];
 34     sv41.backgroundColor = [UIColor groupTableViewBackgroundColor];
 35     sv51.backgroundColor = [UIColor grayColor];
 36     sv61.backgroundColor = [UIColor lightGrayColor];
 37 
 38 
 39     // 添加
 40     [self.view addSubview:sv11];
 41     [self.view addSubview:sv12];
 42     [self.view addSubview:sv13];
 43     [self.view addSubview:sv14];
 44     [self.view addSubview:sv15];
 45 
 46     [self.view addSubview:sv21];
 47     [self.view addSubview:sv31];
 48     [self.view addSubview:sv41];
 49     [self.view addSubview:sv51];
 50     [self.view addSubview:sv61];
 51 
 52 
 53     // 开始约束
 54     [sv11 mas_makeConstraints:^(MASConstraintMaker *make) {
 55 
 56         make.size.mas_equalTo(CGSizeMake(180, 180));
 57     }];
 58 
 59     [sv12 mas_makeConstraints:^(MASConstraintMaker *make) {
 60 
 61         make.size.mas_equalTo(CGSizeMake(70, 20));
 62     }];
 63     
 64     [sv13 mas_makeConstraints:^(MASConstraintMaker *make) {
 65         
 66         // 决定了在第几列开始纵向布局
 67         make.centerY.equalTo(@[sv11,sv12,sv14,sv15]);
 68         make.centerX.equalTo(@[sv21,sv31,sv41,sv51,sv61]);
 69         make.size.mas_equalTo(CGSizeMake(50, 50));
 70     }];
 71     [sv14 mas_makeConstraints:^(MASConstraintMaker *make) {
 72         make.size.mas_equalTo(CGSizeMake(20, 60));
 73     }];
 74     [sv15 mas_makeConstraints:^(MASConstraintMaker *make) {
 75         make.size.mas_equalTo(CGSizeMake(40, 30));
 76     }];
 77 
 78     [sv21 mas_makeConstraints:^(MASConstraintMaker *make) {
 79         make.size.mas_equalTo(CGSizeMake(50, 20));
 80     }];
 81     [sv31 mas_makeConstraints:^(MASConstraintMaker *make) {
 82         make.size.mas_equalTo(CGSizeMake(50, 20));
 83     }];
 84     [sv41 mas_makeConstraints:^(MASConstraintMaker *make) {
 85         make.size.mas_equalTo(CGSizeMake(40, 60));
 86     }];
 87     [sv51 mas_makeConstraints:^(MASConstraintMaker *make) {
 88         make.size.mas_equalTo(CGSizeMake(50, 20));
 89     }];
 90     [sv61 mas_makeConstraints:^(MASConstraintMaker *make) {
 91         make.size.mas_equalTo(CGSizeMake(50, 20));
 92     }];
 93 
 94     // 横向
 95     [self.view distributeSpacingHorizontallyWith:@[sv11,sv12,sv13,sv15,sv14]];
 96     
 97     // 纵向:sv14 可换做 sv11,sv12,sv13,sv15,任取其一即可
 98     [self.view distributeSpacingVerticallyWith:@[sv14,sv21,sv31,sv41,sv51,sv61]];
 99 }
100 
101 @end
复制代码

运行效果:技巧就是使用空白的占位(间距)来填充我们目标 view 的旁边空间

 

posted on   低头捡石頭  阅读(29)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示