MasonryFloatLayout : 基于Masonry的浮动布局
前言
在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];
- 在上面增加束缚过程中,我们需要使用
lastFloatConstraint
和nextFloatConstraint
,这两个属性都是来源于 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传送门
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » MasonryFloatLayout : 基于Masonry的浮动布局
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » MasonryFloatLayout : 基于Masonry的浮动布局