MasonryFloatLayout : 基于Masonry的浮动布局

  • 时间:2022-03-15 15:04 作者:神经骚栋 来源: 阅读:333
  • 扫一扫,手机访问
摘要:前言在iOS中使用Masonry进行布局算是日常操作,但是相似于网页的浮动布局的时候,具体示用意如下.移除其中的某个元素,剩下的元素就会往某个方向进行移动,在Web端,这种布局方式就叫做浮动布局.另外还有下面的这种情况,尽管也进行浮动但是依然还另外一边保持着束缚关系,这一种在iOS也是比较常见的束缚


前言


在iOS中使用Masonry进行布局算是日常操作,但是相似于网页的浮动布局的时候,具体示用意如下.

移除其中的某个元素,剩下的元素就会往某个方向进行移动,在Web端,这种布局方式就叫做浮动布局.

另外还有下面的这种情况,尽管也进行浮动但是依然还另外一边保持着束缚关系,这一种在iOS也是比较常见的束缚情况.

在iOS的Masonry使用实现上述过程其实非常麻烦的,假如是我们基于Masonry,基于这种情况,我们一般会有两种写法,一种是状态穷举法,另外一种是临时视图变量记录法.

状态穷举法例:

状态穷举法就是所有的视图组合情况列举出来而后增加对应的束缚布局.具体示例可以看下面代码.

- (void)loseConstraintsAction {    if (!_A.hidden && !_B.hidden && !_C.hidden) {        [_A mas_remakeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo(self.view).offset(20.0f);        }];        [_B mas_remakeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo(self.A.mas_right).offset(8.0f);        }];        [_C mas_remakeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo(self.B.mas_right).offset(8.0f);        }];    }        if (!_A.hidden && _B.hidden && !_C.hidden) {        [_A mas_remakeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo(self.view).offset(20.0f);        }];        [_C mas_remakeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo(self.A.mas_right).offset(8.0f);        }];    }    if (_A.hidden && _B.hidden && !_C.hidden) {        [_C mas_remakeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo(self.view).offset(8.0f);        }];    }}

状态穷举法算是非常暴力的方案了.状态穷举法的写法形式多种多样,但是整体思想是一致的, 穷举法尽管了解起来简单, 但是弊端也是显而易见的,代码量却是不容小觑,每添加一种组合,我们就需要多一种束缚方案.....


临时视图变量记录法:

临时变量记录法就是使用一个临时变量记录与哪个视图建立束缚,具体的代码示例如下所示.

- (void)loseConstraintsAction {    UIView *lastView = self.view;    if (!_A.hidden) {        [_A mas_remakeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo([lastView isEqual:self.view] ? lastView : lastView.mas_right).offset(20.0f);        }];        lastView = _A;    }    if (!_B.hidden) {        [_B mas_remakeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo([lastView isEqual:self.view] ? lastView : lastView.mas_right).offset(8.0f);        }];        lastView = _B;    }    if (!_C.hidden) {        [_C mas_remakeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo([lastView isEqual:self.view] ? lastView : lastView.mas_right).offset(8.0f);        }];    }}

相比于穷举法,在代码结构上已经有很大的改观,但是整体代码依然让人感觉不是那么满意.

由此骚栋就在想能否可以基于Masonry封装一个库,来实现这种浮动效果呢? 所以我就封装了一个基于Masonry的浮动布局 MasonryFloatLayout.

在说实现之前,我们先看一下如何使用封装好的 MasonryFloatLayout.


MasonryFloatLayout的使用


  • 首先先导入Demo中 MasonryFloatLayout 文件夹,如下图所示.
image
  • 这里需要改动的就是 UIViewFloatLayoutHeader 的Masonry的文件路径地址,假如报错,请导入正确的文件路径地址.
#ifndef UIViewFloatLayoutHeader_h#define UIViewFloatLayoutHeader_h#import "Masonry/Masonry.h"#endif /* UIViewFloatLayoutHeader_h */
  • 在需要的ViewController或者者View中引入头文件.
#import "NSArray+FloatLayout.h"
  • 假设我们现在有三个View,需要进行浮动布局,那么我们先要把初始化工作完成.包括公告View属性和懒加载View方法实现,当然了,你可以按照你的习惯来.
@property (nonatomic, strong) UIView *firstView;@property (nonatomic, strong) UIView *secondView;@property (nonatomic, strong) UILabel *thirdView;
- (UIView *)firstView {    if (_firstView == nil) {        _firstView = [[UIView alloc] initWithFrame:CGRectZero];        _firstView.backgroundColor = [UIColor redColor];    }    return _firstView;}- (UIView *)secondView {    if (_secondView == nil) {        _secondView = [[UIView alloc] initWithFrame:CGRectZero];        _secondView.backgroundColor = [UIColor orangeColor];    }    return _secondView;}- (UILabel *)thirdView {    if (_thirdView == nil) {        _thirdView = [[UILabel alloc] initWithFrame:CGRectZero];        _thirdView.backgroundColor = [UIColor blueColor];        _thirdView.textColor = [UIColor whiteColor];        _thirdView.text = @"333333333333";    }    return _thirdView;}
  • 接下来我们需要浮动束缚布局的增加了.和Masonry布局一样,首先我们需要使用mas_remakeFloatLayoutConstraints给每一个View增加具体的布局.最后再用数组增加浮动布局.具体代码如下所示.
    [self.firstView mas_remakeFloatLayoutConstraints:^(MASConstraintMaker * _Nonnull make, UIView * _Nonnull lastView, UIView * _Nonnull nextView) {        make.left.equalTo(@50);        make.height.equalTo(@100);        make.width.equalTo(@100);        make.lastFloatConstraint.offset(10.0f);        make.nextFloatConstraint.offset(-10.0f).priorityHigh();    }];    [self.secondView mas_remakeFloatLayoutConstraints:^(MASConstraintMaker * _Nonnull make, UIView * _Nonnull lastView, UIView * _Nonnull nextView) {        make.left.equalTo(@50);        make.height.equalTo(@100);        make.width.equalTo(@100);        make.lastFloatConstraint.offset(30.0f).priorityLow();        make.nextFloatConstraint.offset(-10.0f);    }];    [self.thirdView mas_remakeFloatLayoutConstraints:^(MASConstraintMaker * _Nonnull make, UIView * _Nonnull lastView, UIView * _Nonnull nextView) {        make.left.equalTo(@50);        make.height.equalTo(@100);        make.lastFloatConstraint.offset(10.0f);        make.nextFloatConstraint.offset(-10.0f);    }];    [@[self.thirdView, self.firstView, self.secondView] mas_remakeFloatLayoutConstraintsWithOrientation:FloatLayoutOrientationBottomToTop needLastConstraint:need];
  • 在上面增加束缚过程中,我们需要使用 lastFloatConstraintnextFloatConstraint,这两个属性都是来源于 MASConstraintMaker+FloatLayout,我们可以通过这两个属性增加与上一个View和下一个View的间距关系.
@property (nonatomic, strong) MASFloatLayoutConstraint *lastFloatConstraint;@property (nonatomic, strong) MASFloatLayoutConstraint *nextFloatConstraint;
  • 当然了,间距关系也可以设置优先级,这样的话.假如有间距束缚冲突,通过设置优先级来处理这种问题.这在上面的示例中也是有所表现.
- (MASFloatLayoutConstraint * (^)(MASLayoutPriority priority))priority;- (MASFloatLayoutConstraint * (^)(void))priorityLow;- (MASFloatLayoutConstraint * (^)(void))priorityMedium;- (MASFloatLayoutConstraint * (^)(void))priorityHigh;
  • mas_remakeFloatLayoutConstraints 方法的Block参数除了常见的MASConstraintMaker *make 之外,还会返回上一个视图lastView和下一个视图nextView,当然了,这两个参数有可能是nil.
typedef void(^FloatConstraintMaker)(MASConstraintMaker *make, UIView *lastView, UIView *nextView);
  • 每一个视图的束缚增加完成之后,我们增加浮动布局,浮动布局是基于NSArray的分类 NSArray+FloatLayout, mas_remakeFloatLayoutConstraintsWithOrientation 方法总共有两个参数.一个是用来设定浮动的方向,另外一个是用来设定最后一个视图与父视图的关系,相似于上一个模块说到的第二种情况.
typedef enum : NSUInteger {    FloatLayoutOrientationUnknow,      // 未知或者者根据自己设置的束缚进行束缚布局    FloatLayoutOrientationLeftToRight, // 从左到右进行布局    FloatLayoutOrientationRightToLeft, // 从右到左进行布局    FloatLayoutOrientationTopToBottom, // 从上到下进行布局    FloatLayoutOrientationBottomToTop, // 从下到上进行布局} FloatLayoutOrientation;/// 执行浮动布局/// @param orientation 相对于父视图的浮动方向/// @param needLastConstraint 能否需要增加最后的束缚- (void)mas_remakeFloatLayoutConstraintsWithOrientation:(FloatLayoutOrientation)orientation                                     needLastConstraint:(BOOL)needLastConstraint;

整体的使用流程就是这样的.整体来说和原来的Masonry布局代码方式没有什么太大区别.具体的示例可以看一下我的Demo.


总结


假如在使用过程中遇到任何疑问欢迎随时找我,骚栋在这里谢谢大家了.

MasonryFloatLayout传送门


  • 全部评论(0)
最新发布的资讯信息
【系统环境|】2FA验证器 验证码如何登录(2024-04-01 20:18)
【系统环境|】怎么做才能建设好外贸网站?(2023-12-20 10:05)
【系统环境|数据库】 潮玩宇宙游戏道具收集方法(2023-12-12 16:13)
【系统环境|】遥遥领先!青否数字人直播系统5.0发布,支持真人接管实时驱动!(2023-10-12 17:31)
【系统环境|服务器应用】克隆自己的数字人形象需要几步?(2023-09-20 17:13)
【系统环境|】Tiktok登录教程(2023-02-13 14:17)
【系统环境|】ZORRO佐罗软件安装教程及一键新机使用方法详细简介(2023-02-10 21:56)
【系统环境|】阿里云 centos 云盘扩容命令(2023-01-10 16:35)
【系统环境|】补单系统搭建补单源码搭建(2022-05-18 11:35)
【系统环境|服务器应用】高端显卡再度登上热搜,竟然是因为“断崖式”的降价(2022-04-12 19:47)
手机二维码手机访问领取大礼包
返回顶部