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 的旁边空间
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)