IOS不用AutoLayout也能实现自动布局的类(4)----MyTableLayout横空出世

界面库下载地址:

https://github.com/youngsoft/MyLinearLayout      

        前面的几篇文章里我分别介绍了线性布局(MyLinearLayout),相对布局(MyRelativeLayout),框架布局(MyFrameLayout)这三种布局。这三种布局中 :

线性布局主要应用于容器视图里面的所有子视图依次从上往下排列或者从左往右排列的场景。

垂直线性布局

子视图1
子视图2
子视图3
子视图4


水平线性布局

子视图1 子视图2 子视图3 子视图4


当然我们也可以用线性布局嵌套线性布局的方法来实现一些复杂的界面布局,比如(这个例子如果用MyTableLayout实现将更加简单):


复杂布局

水平线性布局子视图1 水平线性布局子视图2

子视图1 子视图2 子视图3

子视图1
子视图2
子视图3


相对布局主要用于容器视图中的各个子视图之间的位置和高宽以及子视图和容器视图之间具有一定的依赖和约束关系的场景。比如说子视图1的位置在子视图2的右下角,并且宽度等于子视图3的宽度,而子视图3的底部又在容器视图的底部。

           

相对布局

子视图1(等宽3)    
  子视图2  
    子视图3(等宽1)

相对布局因为需要指定各子视图之间的依赖关系,因此如果设置不当就会产生递归死循环的情况,而且在某种程度上不利于子视图之间的位置的更新和变化等等,其中IOS自带的AutoLayout其实就是一套相对布局的实现,相对布局功能很强大也可以很容易布局复杂的界面,缺点是使用不当的话就容易造成约束死循环的情况。


框架布局主要用于容器视图中的个子视图在容器视图的上,中,下,左,中,右,拉升填充,居中显示等11种情况。

框架布局

左上 中上 右上
左中 居中 右中
左下 中下 右下


框架布局中的子视图只跟容器视图之间产生关系,子视图之间没有任何关联关系。


一、表格布局的介绍


    在一些实际的应用界面中,我们希望我们的子视图以表格的形式展示出来,这些表格展示可以是正规的几行几列并且固定高宽的形式,也可能是每一行的列数都不同,也可能是每行的高度不一样,也可能是一行内的各列的宽度也不一样,


               水平表格布局

IOS不用AutoLayout也能实现自动布局的类(4)----MyTableLayout横空出世_第1张图片                                                                                                                                       

                                                                                                                                                 垂直表格布局

IOS不用AutoLayout也能实现自动布局的类(4)----MyTableLayout横空出世_第2张图片





















要实现上面的两种界面风格,我们可以借助MyTableLayout来实现。


MyTableLayout是从MyLinearLayout中继承而来,因此表格布局也分为垂直表格布局和水平表格布局,样式请参考上面的图例的展示风格。而表格的风格样式同样通过

orientation属性来设置。不管是垂直表格布局还是水平表格布局。我们在建立了表格布局视图并指定了表格风格后,我们首先的步骤是要为表格添加行(如果是水平表格其实就是添加列,下面如果为说明都是如此概念),那这个步骤可以通过MyTableLayout的方法:


-(void)addRow:(CGFloat)rowHeight colWidth:(CGFloat)colWidth;

-(void)insertRow:(CGFloat)rowHeight colWidth:(CGFloat)colWidth atIndex:(NSInteger)rowIndex;


来实现,前者是往表格布局尾部添加一行,而后者则是在指定的位置插入一行。这里需要说明的参数是rowHeight,colWidth的意义,我们知道只要我们插入一行时我们总是需要指出插入的这一行的行高是多少,同时要指出插入的这行的列单元格的宽度是如何指定的(每列的宽度固定,还是有单元格自己指定等等)


 rowHeight-1时表示由最高的单元格视图决定本行高度,每个单元格视图需要自己设置高度;为0表示均分高度,单元格视图不需要设置高度;大于0表示固定高度,单元格视图不需要设置高度.


 colWidth -2时表示每个单元格视图需要自己指定宽度,整体行宽和表格布局一致;为-1表示每个单元格视图需要自己指定宽度,整个行宽包裹所有子视图;为0表示均分宽度,这时候单元格视图不必设置宽度;大于0表示单元格视图固定宽度,这时候单元格视图可以不必设置宽度。


同时我们也提供了对行操作的其他方法:


//删除指定的行

-(void)removeRowAt:(NSInteger)rowIndex;

//交行两个行的内容

-(void)exchangeRowAt:(NSInteger)rowIndex1 withRow:(NSInteger)rowIndex2;

//得到行视图,从返回我们可以看出,我们调用插入行操作时,系统内部会自动建立一个MyLinearLayout线性布局视图作为行视图,如果是垂直表格则默认是水平线性布局,而如果是水平表格则默认是垂直线性布局,因此我们可以通过这个方法来设置行的其他的各种属性,比如说行间距(xxxMargin来实现)。

-(MyLinearLayout*)viewAtRowIndex:(NSInteger)rowIndex;

//返回当前有多少行

-(NSUInteger)countOfRow;



当我们插入了一行后,我们就需要为这一行添加单元格视图(列视图),每一行都可以无限制的添加单元格视图,也就是说一行可以有很多的列,每一行的列数都可以不一样,我们可以通过如下的方法来添加或者删除列:


-(void)addCol:(UIView*)colView atRow:(NSInteger)rowIndex;

-(void)insertCol:(UIView*)colView atIndexPath:(NSIndexPath*)indexPath;

-(void)removeColAt:(NSIndexPath*)indexPath;

-(void)exchangeColAt:(NSIndexPath*)indexPath1 withCol:(NSIndexPath*)indexPath2;


注意上面的添加列时,需要指定在哪一行添加列,在添加列之前必须要把行添加进去,也就是说行索引rowIndex不能越界,为了简单的描述行索引和列索引的关系我们使用了NSIndexPath这个对象来描述,我们对NSIndexPath进行了扩展,以便用于方便的指定行和列的索引:


@interface NSIndexPath(MyTableLayoutEx)


+(instancetype)indexPathForCol:(NSInteger)col inRow:(NSInteger)row;


@property(nonatomic,assign,readonly)NSInteger col;


@end



同时我们也方便的提供了单元格列视图的获取和数量的获取的方法

//返回列视图

-(UIView*)viewAtIndexPath:(NSIndexPath*)indexPath;

//返回指定行的列的数量。

-(NSUInteger)countOfColInRow:(NSInteger)rowIndex;


 


 

上面就是我们对表格布局的所有函数的介绍,使用起来也很简单,步骤就是先添加行,然后在每行中依次一个个的添加列视图,也就是单元格视图。


 

我们将分别建立两个风格的表格进行例子的说明。


 


 

二、垂直表格  


 

   所谓垂直表格就是行是从上往下,一行一行布局起来的,所有行内的单元格视图都是从左往右一列一列布局起来的,建立垂直表格是默认的表格。先看界面布局效果。


 


 

IOS不用AutoLayout也能实现自动布局的类(4)----MyTableLayout横空出世_第3张图片  
 


 


 


 

我们分别建立了6行不同尺寸的表格,上可以看出每一行的列数不一样,每一行的高度不一样,每一行的总体列宽不一样,每一行的每一列的宽度都不一样,而这些我们都是通过在插入行时通过设置不同的rowHeight,colWidth来达到效果的。具体代码参考如下:


 

-(void)loadView
{
    [super loadView];
    
    /*
     有的时候我们希望让一个布局视图放入到非布局视图中去,但又希望布局视图的宽高和非布局父视图宽高一致。
     这时候我们可以设置height,width来指定自身的高宽,我们也可以通过leftMargin = 0,rightMargin = 0来让其跟父视图保持一样的宽度,但如果是这样的话还需要设置wrapContentWidth = NO. 设置高度同理。
     */
    MyTableLayout *tbll = [MyTableLayout new];
    tbll.wrapContentHeight = NO;  //对于线性布局来说必须要设置为NO才能高度和非布局的父视图一样高
    tbll.leftMargin = tbll.rightMargin = 0;  //宽度和非布局父视图一样宽
    tbll.topMargin = tbll.bottomMargin = 0;  //高度和非布局父视图一样高
    [self.view addSubview:tbll];

    
    //第一行固定高度固定宽度
    [tbll addRow:30 colWidth:30];
    [tbll viewAtRowIndex:0].backgroundColor = [UIColor colorWithWhite:0.1 alpha:1];
    
    UIView *colView = [UIView new];
    colView.leftMargin = 10; //可以使用leftMargin,topMargin,rightMargin,bottomMargin来调整间隔
    colView.topMargin = 5;
    colView.bottomMargin = 5;
    colView.rightMargin = 40;
    
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:0];
    
    colView = [UIView new];
    colView.leftMargin = 20;
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:0];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor blueColor];
    [tbll addCol:colView atRow:0];
    
    //第二行固定高度,均分宽度
    [tbll addRow:40 colWidth:0];
    [tbll viewAtRowIndex:1].backgroundColor = [UIColor colorWithWhite:0.2 alpha:1];

    
    colView = [UIView new];
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:1];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:1];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor blueColor];
    [tbll addCol:colView atRow:1];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor yellowColor];
    [tbll addCol:colView atRow:1];
    
    //第三行固定高度,子视图自己决定宽度。
    [tbll addRow:30 colWidth:-1];
    [tbll viewAtRowIndex:2].backgroundColor = [UIColor colorWithWhite:0.3 alpha:1];
    colView = [UIView new];
    colView.width = 100;
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:2];

    colView = [UIView new];
    colView.width = 200;
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:2];
    
    //第四行固定高度,子视图自己决定宽度。
    [tbll addRow:30 colWidth:-2];
    [tbll viewAtRowIndex:3].backgroundColor = [UIColor colorWithWhite:0.4 alpha:1];
    colView = [UIView new];
    colView.width = 80;
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:3];
    
    colView = [UIView new];
    colView.width = 200;
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:3];
    
    //第五行高度均分.这里设置为0表示剩余高度再均分。宽度均分,
    [tbll addRow:0 colWidth:0];
    MyLinearLayout *row4 = [tbll viewAtRowIndex:4];
    //可以设置行的属性.比如padding, 线条颜色,
    row4.padding = UIEdgeInsetsMake(3, 3, 3, 3);
    row4.topBorderLine = [[MyBorderLineDraw alloc] initWithColor:[UIColor blackColor]];
    row4.topBorderLine.thick = 2;
    row4.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1];

    colView = [UIView new];
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:4];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:4];
    
    //第六行高度由子视图决定,均分宽度
    [tbll addRow:-1 colWidth:0];
    [tbll viewAtRowIndex:5].backgroundColor = [UIColor colorWithWhite:0.6 alpha:1];
    
    colView = [UIView new];
    colView.height = 80;
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:5];
    
    colView = [UIView new];
    colView.height = 120;
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:5];
    
    colView = [UIView new];
    colView.height = 70;
    colView.backgroundColor = [UIColor blueColor];
    [tbll addCol:colView atRow:5];





    
    
}

 
上面的代码中我们在插入行时分别为rowHeight,colWidth设置了6种不同的参数的组合,我们看到其中有些行中需要指定每个单元格的列宽和行高,而有的则不需要。是否需要单元格指定行高和列宽则是有rowHeight,colWidth的不同的参数值决定的。 有时候我们的表格可能需要指定行间距和列间距,而这些都可以通过行视图的xxMargin, 和列视图的xxxMargin的设置来进行个性化的定制,这里需要强调一下rowHeight,colWidth都等于0的情况,他们的意义是表示行和列会均分高度和宽度。


 

  举例来说,假设我们建立了一个宽高为100*100的表格布局,而我们第一行的rowHeight,colWidth设置为0时,则当插入第一行时则这一行的高度就是100,而这一行插入第一列时则这一列的宽度就是100,而如果再插入一列时则两列的宽度都会调整为50,同样当我们再次插入一行时则两行的高度都将会调整为50. (这个像不像HTML中的表格的行列的宽高指定的风格)


 


 


 


 

三、水平表格(瀑布流)  


 

      所谓水平表格就是行是从左往右,一行一行布局起来的,所有行内的单元格视图都是从上往下一列一列布局起来的,建立水平表格需要将  

orientation = LVORIENTATION_HORZ, 水平表格也就是一个瀑布流风格的表格,我们可以通过将表格放入到UIScrollView中进行从上到下的滚动以便展示所有内容。先看界面布局效果:


IOS不用AutoLayout也能实现自动布局的类(4)----MyTableLayout横空出世_第4张图片



这个例子我们也跟上面一样,建立了6行(注意水平表格里面行的概念就是指列,而列则是指行),同时我们把表格布局加入到了一个UIScrollView下,以便能有滚动的效果。我们为了延长表格的高度,我们对第三行的第三个单元格视图特意设置了一个很高的高度。代码如下:


-(void)loadView
{
    [super loadView];
    
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    scrollView.autoresizingMask =  UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    [self.view addSubview:scrollView];
    
    
    
    /*
     有的时候我们希望让一个布局视图放入到非布局视图中去,但又希望布局视图的宽高和非布局父视图宽高一致。
     这时候我们可以设置height,width来指定自身的高宽,我们也可以通过leftMargin = 0,rightMargin = 0来让其跟父视图保持一样的宽度,但如果是这样的话还需要设置wrapContentWidth = NO. 设置高度同理。
     */
    MyTableLayout *tbll = [MyTableLayout new];
    tbll.orientation = LVORIENTATION_HORZ;
    tbll.wrapContentWidth = NO;  //对于线性布局来说必须要设置为NO才能宽度和非布局的父视图一样宽
    tbll.wrapContentHeight = YES; //这里设定高度由子视图决定。
    tbll.leftMargin = tbll.rightMargin = 0;  //宽度和非布局父视图一样宽
    [scrollView addSubview:tbll];
    
    
    //需要注意的是因为这里的表格设置为水平表格,所以下面所的行高,其实是行宽,而列宽,其实是列高
    
    
    //第一行固定高度固定宽度
    [tbll addRow:30 colWidth:30];
    [tbll viewAtRowIndex:0].backgroundColor = [UIColor colorWithWhite:0.1 alpha:1];
    
    UIView *colView = [UIView new];
    colView.leftMargin = 5; //可以使用leftMargin,topMargin,rightMargin,bottomMargin来调整间隔
    colView.topMargin = 5;
    colView.bottomMargin = 5;
    colView.rightMargin = 5;
    
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:0];
    
    colView = [UIView new];
    colView.topMargin = 20;
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:0];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor blueColor];
    [tbll addCol:colView atRow:0];
    
    //第二行固定高度,均分宽度
    [tbll addRow:40 colWidth:0];
    [tbll viewAtRowIndex:1].backgroundColor = [UIColor colorWithWhite:0.2 alpha:1];
    
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:1];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:1];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor blueColor];
    [tbll addCol:colView atRow:1];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor yellowColor];
    [tbll addCol:colView atRow:1];
    
    //第三行固定高度,子视图自己决定宽度。
    [tbll addRow:30 colWidth:-1];
    [tbll viewAtRowIndex:2].backgroundColor = [UIColor colorWithWhite:0.3 alpha:1];
    colView = [UIView new];
    colView.height = 100;
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:2];
    
    colView = [UIView new];
    colView.height = 200;
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:2];
    
    colView = [UIView new];
    colView.height = 1000;
    colView.backgroundColor = [UIColor blueColor];
    [tbll addCol:colView atRow:2];
    
    //第四行固定高度,子视图自己决定宽度。
    [tbll addRow:30 colWidth:-2];
    [tbll viewAtRowIndex:3].backgroundColor = [UIColor colorWithWhite:0.4 alpha:1];
    colView = [UIView new];
    colView.height = 80;
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:3];
    
    colView = [UIView new];
    colView.height = 200;
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:3];
    
    //第五行高度均分.这里设置为0表示剩余高度再均分。宽度均分,
    [tbll addRow:0 colWidth:0];
    MyLinearLayout *row4 = [tbll viewAtRowIndex:4];
    //可以设置行的属性.比如padding, 线条颜色,
    row4.padding = UIEdgeInsetsMake(3, 3, 3, 3);
    row4.leftBorderLine = [[MyBorderLineDraw alloc] initWithColor:[UIColor blackColor]];
    row4.leftBorderLine.thick = 2;
    row4.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:4];
    
    colView = [UIView new];
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:4];
    
    //第六行高度由子视图决定,均分宽度
    [tbll addRow:-1 colWidth:0];
    [tbll viewAtRowIndex:5].backgroundColor = [UIColor colorWithWhite:0.6 alpha:1];
    
    colView = [UIView new];
    colView.width = 80;
    colView.backgroundColor = [UIColor redColor];
    [tbll addCol:colView atRow:5];
    
    colView = [UIView new];
    colView.width = 120;
    colView.backgroundColor = [UIColor greenColor];
    [tbll addCol:colView atRow:5];
    
    colView = [UIView new];
    colView.width = 70;
    colView.backgroundColor = [UIColor blueColor];
    [tbll addCol:colView atRow:5];
    
    
    
    
    
    
}

 
这段代码的内容和上面的垂直表格相似,只是把一些原来的宽度值改为了高度值而已。


四、总结

    好了,表格布局的内容就介绍到这里了,表格布局的内部实现其实就是一个线性布局套线性布局的封装,但是他简化了我们插入视图的方法,从而很容易的布局出各种风格的布局,我们可以从上往下依次布局,也可以从左往右依次布局。如果您觉得这篇文章能够帮助到您,或者能成为您界面布局的解决方案,那么请到我的github:


https://github.com/youngsoft/MyLinearLayout 中下载这套界面解决框架库,如果您觉得好用就记得给我点赞哦,如果有什么不明确的可以加我QQ:156355113联系我。

















你可能感兴趣的:(ios,表格布局,自动布局,autolayout)