知识点:

1.masonry

2.NSArray分类实现

NSArray+Sudoku.h


#import "MASUtilities.h"
#import "MASConstraintMaker.h"
#import "MASViewAttribute.h"
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface NSArray (Sudoku)/***  九宫格布局 固定ItemSize 可变ItemSpacing**  @param fixedItemWidth  固定宽度*  @param fixedItemHeight 固定高度*  @param warpCount       折行点*  @param topSpacing      顶间距*  @param bottomSpacing   底间距*  @param leadSpacing     左间距*  @param tailSpacing     右间距*/
- (void)mas_distributeSudokuViewsWithFixedItemWidth:(CGFloat)fixedItemWidthfixedItemHeight:(CGFloat)fixedItemHeightwarpCount:(NSInteger)warpCounttopSpacing:(CGFloat)topSpacingbottomSpacing:(CGFloat)bottomSpacingleadSpacing:(CGFloat)leadSpacingtailSpacing:(CGFloat)tailSpacing;/***  九宫格布局 可变ItemSize 固定ItemSpacing**  @param fixedLineSpacing      行间距*  @param fixedInteritemSpacing 列间距*  @param warpCount             折行点*  @param topSpacing            顶间距*  @param bottomSpacing         底间距*  @param leadSpacing           左间距*  @param tailSpacing           右间距*/
- (void)mas_distributeSudokuViewsWithFixedLineSpacing:(CGFloat)fixedLineSpacingfixedInteritemSpacing:(CGFloat)fixedInteritemSpacingwarpCount:(NSInteger)warpCounttopSpacing:(CGFloat)topSpacingbottomSpacing:(CGFloat)bottomSpacingleadSpacing:(CGFloat)leadSpacingtailSpacing:(CGFloat)tailSpacing;/***  九宫格布局 固定ItemSize 固定ItemSpacing*  可由九宫格的内容控制SuperView的大小*  如果warpCount大于[self count],该方法将会用空白的View填充到superview中**  Sudoku Layout, has fixed item size, and fix item space*  If warp count greater than self.count, It's fill empty view to superview**  @param fixedItemWidth        固定宽度,如果设置成0,则表示自适应,If set it to zero, indicates the adaptive.*  @param fixedItemHeight       固定高度,如果设置成0,则表示自适应,If set it to zero, indicates the adaptive.*  @param fixedLineSpacing      行间距*  @param fixedInteritemSpacing 列间距*  @param warpCount             折行点*  @param topSpacing            顶间距*  @param bottomSpacing         底间距*  @param leadSpacing           左间距*  @param tailSpacing           右间距**  @return 一般情况下会返回[self copy], 如果warpCount大于[self count],则会返回一个被空白view填充过的数组,可以让你循环调用removeFromSuperview或者干一些其他的事情;*  @return Normal will return [self copy], If warpCount bigger than [self count] , It will return a empty views filled array, you could enumerate [subview removeFromSuperview] or do other things;*/
- (NSArray *)mas_distributeSudokuViewsWithFixedItemWidth:(CGFloat)fixedItemWidthfixedItemHeight:(CGFloat)fixedItemHeightfixedLineSpacing:(CGFloat)fixedLineSpacingfixedInteritemSpacing:(CGFloat)fixedInteritemSpacingwarpCount:(NSInteger)warpCounttopSpacing:(CGFloat)topSpacingbottomSpacing:(CGFloat)bottomSpacingleadSpacing:(CGFloat)leadSpacingtailSpacing:(CGFloat)tailSpacing;
@endNS_ASSUME_NONNULL_END

NSArray+Sudoku.m


#import "NSArray+Sudoku.h"
#import "View+MASAdditions.h"@implementation NSArray (Sudoku)
- (MAS_VIEW *)star_commonSuperviewOfViews {if (self.count == 1) {return ((MAS_VIEW *)self.firstObject).superview;}MAS_VIEW *commonSuperview = nil;MAS_VIEW *previousView = nil;for (id object in self) {if ([object isKindOfClass:[MAS_VIEW class]]) {MAS_VIEW *view = (MAS_VIEW *)object;if (previousView) {commonSuperview = [view mas_closestCommonSuperview:commonSuperview];} else {commonSuperview = view;}previousView = view;}}NSAssert(commonSuperview, @"Can't constrain views that do not share a common superview. Make sure that all the views in this array have been added into the same view hierarchy.");return commonSuperview;
}- (void)mas_distributeSudokuViewsWithFixedItemWidth:(CGFloat)fixedItemWidthfixedItemHeight:(CGFloat)fixedItemHeightwarpCount:(NSInteger)warpCounttopSpacing:(CGFloat)topSpacingbottomSpacing:(CGFloat)bottomSpacingleadSpacing:(CGFloat)leadSpacingtailSpacing:(CGFloat)tailSpacing {if (self.count < 2) {NSAssert(self.count>1,@"views to distribute need to bigger than one");return;}if (warpCount < 1) {NSAssert(false, @"warp count need to bigger than zero");return;}MAS_VIEW *tempSuperView = [self star_commonSuperviewOfViews];NSInteger rowCount = self.count % warpCount == 0 ? self.count / warpCount : self.count / warpCount + 1;MAS_VIEW *prev;for (int i = 0; i < self.count; i++) {MAS_VIEW *v = self[i];// 当前行NSInteger currentRow = i / warpCount;// 当前列NSInteger currentColumn = i % warpCount;[v mas_makeConstraints:^(MASConstraintMaker *make) {// 固定宽度make.width.equalTo(@(fixedItemWidth));make.height.equalTo(@(fixedItemHeight));// 第一行if (currentRow == 0) {make.top.equalTo(tempSuperView).offset(topSpacing);}// 最后一行if (currentRow == rowCount - 1) {make.bottom.equalTo(tempSuperView).offset(-bottomSpacing);}// 中间的若干行if (currentRow != 0 && currentRow != rowCount - 1){CGFloat offset = (1-(currentRow/((CGFloat)rowCount-1)))*(fixedItemHeight+topSpacing)-currentRow*bottomSpacing/(((CGFloat)rowCount-1));make.bottom.equalTo(tempSuperView).multipliedBy(currentRow/((CGFloat)rowCount-1)).offset(offset);}// 第一列if (currentColumn == 0) {make.left.equalTo(tempSuperView).offset(leadSpacing);}// 最后一列if (currentColumn == warpCount - 1) {make.right.equalTo(tempSuperView).offset(-tailSpacing);}// 中间若干列if (currentColumn != 0 && currentColumn != warpCount - 1) {CGFloat offset = (1-(currentColumn/((CGFloat)warpCount-1)))*(fixedItemWidth+leadSpacing)-currentColumn*tailSpacing/(((CGFloat)warpCount-1));make.right.equalTo(tempSuperView).multipliedBy(currentColumn/((CGFloat)warpCount-1)).offset(offset);}}];prev = v;}
}- (void)mas_distributeSudokuViewsWithFixedLineSpacing:(CGFloat)fixedLineSpacingfixedInteritemSpacing:(CGFloat)fixedInteritemSpacingwarpCount:(NSInteger)warpCounttopSpacing:(CGFloat)topSpacingbottomSpacing:(CGFloat)bottomSpacingleadSpacing:(CGFloat)leadSpacingtailSpacing:(CGFloat)tailSpacing {[self mas_distributeSudokuViewsWithFixedItemWidth:0 fixedItemHeight:0 fixedLineSpacing:fixedLineSpacing fixedInteritemSpacing:fixedInteritemSpacing warpCount:warpCount topSpacing:topSpacing bottomSpacing:bottomSpacing leadSpacing:leadSpacing tailSpacing:tailSpacing];
}- (NSArray *)mas_distributeSudokuViewsWithFixedItemWidth:(CGFloat)fixedItemWidthfixedItemHeight:(CGFloat)fixedItemHeightfixedLineSpacing:(CGFloat)fixedLineSpacingfixedInteritemSpacing:(CGFloat)fixedInteritemSpacingwarpCount:(NSInteger)warpCounttopSpacing:(CGFloat)topSpacingbottomSpacing:(CGFloat)bottomSpacingleadSpacing:(CGFloat)leadSpacingtailSpacing:(CGFloat)tailSpacing {if (self.count < 1) {return self.copy;}if (warpCount < 1) {NSAssert(false, @"warp count need to bigger than zero");return self.copy;}MAS_VIEW *tempSuperView = [self star_commonSuperviewOfViews];NSArray *tempViews = self.copy;if (warpCount > self.count) {for (int i = 0; i < warpCount - self.count; i++) {MAS_VIEW *tempView = [[MAS_VIEW alloc] init];[tempSuperView addSubview:tempView];tempViews = [tempViews arrayByAddingObject:tempView];}}NSInteger columnCount = warpCount;NSInteger rowCount = tempViews.count % columnCount == 0 ? tempViews.count / columnCount : tempViews.count / columnCount + 1;MAS_VIEW *prev;for (int i = 0; i < tempViews.count; i++) {MAS_VIEW *v = tempViews[i];NSInteger currentRow = i / columnCount;NSInteger currentColumn = i % columnCount;[v mas_makeConstraints:^(MASConstraintMaker *make) {if (prev) {// 固定宽度make.width.equalTo(prev);make.height.equalTo(prev);}else {// 如果写的item高宽分别是0,则表示自适应if (fixedItemWidth) {make.width.equalTo(@(fixedItemWidth));}if (fixedItemHeight) {make.height.equalTo(@(fixedItemHeight));}}// 第一行if (currentRow == 0) {make.top.equalTo(tempSuperView).offset(topSpacing);}// 最后一行if (currentRow == rowCount - 1) {// 如果只有一行if (currentRow != 0 && i-columnCount >= 0) {make.top.equalTo(((MAS_VIEW *)tempViews[i-columnCount]).mas_bottom).offset(fixedLineSpacing);}make.bottom.equalTo(tempSuperView).offset(-bottomSpacing);}// 中间的若干行if (currentRow != 0 && currentRow != rowCount - 1) {make.top.equalTo(((MAS_VIEW *)tempViews[i-columnCount]).mas_bottom).offset(fixedLineSpacing);}// 第一列if (currentColumn == 0) {make.left.equalTo(tempSuperView).offset(leadSpacing);}// 最后一列if (currentColumn == columnCount - 1) {// 如果只有一列if (currentColumn != 0) {make.left.equalTo(prev.mas_right).offset(fixedInteritemSpacing);}make.right.equalTo(tempSuperView).offset(-tailSpacing);}// 中间若干列if (currentColumn != 0 && currentColumn != warpCount - 1) {make.left.equalTo(prev.mas_right).offset(fixedInteritemSpacing);}}];prev = v;}return tempViews;
}
@end

需求实现:

1.固定item宽高

// 创建容器UIView *bg = [UIView new];[self.view addSubview:bg];[bg mas_makeConstraints:^(MASConstraintMaker *make) {if (@available(iOS 11.0, *)) {make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);} else {make.top.equalTo(self.view);}make.left.right.equalTo(self.view);make.height.mas_equalTo(200);}];// 创建itemsNSMutableArray *items = [NSMutableArray array];for (int i = 0; i < 9; i++) {UIButton *item = [UIButton new];item.backgroundColor = [UIColor cyanColor];[bg addSubview:item];[items addObject:item];}// 固定item宽高[items mas_distributeSudokuViewsWithFixedItemWidth:100 fixedItemHeight:50 warpCount:3 topSpacing:10 bottomSpacing:10 leadSpacing:10 tailSpacing:10];

2.固定item大小 固定间隙大小 九宫格大小自适应

#pragma mark - 固定item大小 固定间隙大小 九宫格大小自适应// 创建容器UIView *bg2 = [UIView new];[self.view addSubview:bg2];[bg2 mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(bg.mas_bottom).offset(20);make.left.right.equalTo(self.view);}];// 创建itemsNSMutableArray *items2 = [NSMutableArray array];for (int i = 0; i < 10; i++) {UIButton *item = [UIButton new];item.backgroundColor = [UIColor yellowColor];[bg2 addSubview:item];[items2 addObject:item];}// 固定ItemSize 固定ItemSpacing[items2 mas_distributeSudokuViewsWithFixedItemWidth:80 fixedItemHeight:100 fixedLineSpacing:20 fixedInteritemSpacing:20 warpCount:3 topSpacing:10 bottomSpacing:10 leadSpacing:10 tailSpacing:10];

Masonry实现九宫格布局相关推荐

  1. 【冰极峰教程系列之二】:牢不可破的九宫格布局

    原创:冰极峰 转载请注明出处 时间:2009年6月22日 8:40:16 冰极峰教程系列之一:九宫格基本布局 冰极峰教程系列之二:牢不可破的九宫格布局 冰极峰教程系列之三:三层分离的完美九宫格 冰极峰 ...

  2. iOS回顾笔记( 02 ) -- 由九宫格布局引发的一系列“惨案”

    iOS回顾笔记( 02 ) -- 由九宫格布局引发的一系列"惨案" 前言(扯几句淡先) 回顾到学习UI过程中的九宫格布局时,发现当时学的东西真是不少. 这个阶段最大的特点就是:知识 ...

  3. [html] 实现九宫格布局

    [html] 实现九宫格布局 <style>.container::after{content: "";display: block;clear: both;}.box ...

  4. recycleview 使用详解,添加头部尾部,混合item,侧滑菜单,跳转到指定位置,实现九宫格布局

    添加头部尾部,混合item:https://blog.csdn.net/meixi_android/article/details/82256319 侧滑菜单:https://blog.csdn.ne ...

  5. 首页图标九宫格 html5,html5九宫格布局的网格菜单代码

    特效描述:html5 九宫格布局 网格菜单代码.今天我们想和大家分享一个九宫格菜单动画.这个想法的灵感来自于视频中的效果,html5全屏展开网格布局菜单,点击全屏背景切换显示代码. 代码结构 1. 引 ...

  6. 微信小程序之九宫格布局方案

    2018转眼即将逝去了,由于近期在弄一个小程序的项目的原因,今天在这里记录一下小程序之九宫格布局方案,以备后期需要和相关知识温习. 对于整个小程序项目,原生开发小程序的方式这里就不多说了,官方有确切的 ...

  7. Android笔记-GridView实现九宫格布局

    类似手机系统桌面的九宫格布局,以图片和文字进行搭配,可以使用GridView来实现.类似效果如下: 使用GridView实现过程: 1.在activity_main.xml中修改代码 <Line ...

  8. html九宫格布局原理,了解CSS九宫格布局的几大实现方法

    九宫格布局在制作一些Web App时还是经常可以用到的,本篇文章带大家了解一下CSS九宫格布局的几大实现方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 前提说明 除非特别说明, ...

  9. 关于flex布局和九宫格布局的实现

    1.父容器常见属性 display:flex (项目在主轴上的排列方式) justify-content:flex-start / flex-end / center / space-around / ...

最新文章

  1. 分针网——Javascript不同浏览器差异及兼容方法
  2. 教你用webpack搭一个vue脚手架[超详细讲解和注释!]
  3. why is pricing callback CRM_PRIDOC_UPDATE_EC called
  4. mysql查看执行计划_MySql中如何使用 explain 查询 SQL 的执行计划
  5. ssh免密登陆机制示意图
  6. 鸿蒙官网什么样,鸿蒙系统推广,结果会怎么样?
  7. spring-beanFactory二
  8. oracle中decode函数,行转列
  9. 用requests下载视频
  10. Flutter Android权限问题
  11. 如何测试网站服务器大小,如何测试服务器宽带网络大小
  12. 教你不要光驱一样重装系统
  13. 华为ICT题目-云服务题库1
  14. 算法的复杂度度量--时间复杂度以及空间复杂度
  15. java泛型中T和?和有什么区别
  16. java代码实现乘法口诀表
  17. php主机卫士,Bypass360主机卫士SQL注入防御八种姿势
  18. 测试渲染用什么软件,【2人回答】3DMax2014用的是VRay3.0测试和出图渲染参数怎么设置-3D溜溜网...
  19. 初学Python必备的软件你知道吗?
  20. 仿花生日记官网源码+前后端分离/独立后台

热门文章

  1. 周末要听讲座,不爽~~~
  2. 单例、异常、eval函数
  3. .弧度转角度/角度转弧度
  4. TestFlight:App 不可用或者不存在
  5. android:layout_marginleft的作用,当在FrameLayout中查看时,layout_marginLeft在Android API lt;11上正常工作...
  6. 线代引论:chapter5.2转置(Permutations)和代数余子式(cofactor)
  7. 如何用小数据提升餐厅毛利率
  8. 17组-政务一体化数据平台接口说明
  9. js 限制开始时间到结束时间 最长跨度三个月
  10. linux三剑客(awk,grep,sed)