iOS开发结构--MyLayout
MyLayout 结构不只支撑 Objective-C,也能够在 Swift 中运用。经过 MyLayout,能够运用面向对象的办法来创立和办理视图的布局,简化了 Auto Layout 中繁琐的束缚设置流程。在 Objective-C 中,MyLayout 供给了相同的布局类型和特点,运用办法稍有不同,首要是语法和调用办法上的差异。
先介绍一下怎么运用吧,线性布局和相对布局是用的比较多的布局办法。
1. 线性布局(MyLinearLayout)
线性布局是一种里边的子视图按增加的次序从上到下或许从左到右顺次摆放的单列(单行)布局视图,因而里边的子视图是经过增加的次序树立束缚和依靠联系的。 子视图从上到下顺次摆放的线性布局视图称为笔直线性布局视图,而子视图从左到右顺次摆放的线性布局视图则称为水平线性布局
创立一个笔直线性布局的示例:
MyLinearLayout *rootLayout = [MyLinearLayout linearLayoutWithOrientation:MyOrientation_Vert];
rootLayout.frame = self.view.bounds;
rootLayout.topPos.equalTo(@0);
rootLayout.leftPos.equalTo(@0);
rootLayout.rightPos.equalTo(@0);
rootLayout.bottomPos.equalTo(@0);
// 增加子视图
UIView *view1 = [UIView new];
view1.myHeight = 50;
view1.leftPos.equalTo(@10);
view1.rightPos.equalTo(@10);
[view1 setBackgroundColor:[UIColor redColor]];
[rootLayout addSubview:view1];
UIView *view2 = [UIView new];
view2.myHeight = 100;
view2.leftPos.equalTo(@10);
view2.rightPos.equalTo(@10);
[view2 setBackgroundColor:[UIColor blueColor]];
[rootLayout addSubview:view2];
[self.view addSubview:rootLayout];
在这个比方中,咱们创立了一个笔直线性布局容器 rootLayout
,并在其间增加了两个 UIView
子视图。每个子视图都有自己的高度和边距设置。view1
和 view2
别离设置了不同的高度,且左右边距为 10。
2. 相对布局(MyRelativeLayout)
相对布局答应子视图经过相对父视图或许其他子视图的方位来布局。
相对布局示例:
MyRelativeLayout *rootLayout = [MyRelativeLayout new];
rootLayout.frame = self.view.bounds;
rootLayout.topPos.equalTo(@0);
rootLayout.leftPos.equalTo(@0);
rootLayout.rightPos.equalTo(@0);
rootLayout.bottomPos.equalTo(@0);
UIView *view1 = [UIView new];
view1.mySize = CGSizeMake(100, 100);
view1.centerXPos.equalTo(rootLayout.centerXPos); // 水平居中
view1.topPos.equalTo(@10); // 距离父视图顶部 10
[view1 setBackgroundColor:[UIColor redColor]];
[rootLayout addSubview:view1];
UIView *view2 = [UIView new];
view2.mySize = CGSizeMake(100, 100);
view2.topPos.equalTo(view1.bottomPos).offset(10); // 坐落 view1 底部,距离 10
view2.centerXPos.equalTo(view1.centerXPos); // 水平与 view1 对齐
[view2 setBackgroundColor:[UIColor blueColor]];
[rootLayout addSubview:view2];
[self.view addSubview:rootLayout];
在这个示例中,view1
在父视图中水平居中,而且距离顶部有 10 的距离。而 view2
则坐落 view1
的下方,并坚持水平对齐。经过设置 centerXPos
和 topPos
等特点,MyLayout 能够轻松完结相对布局。
3. 布局结构的类架构
这张图展现了 MyLayout 布局结构的类架构,协助开发者了解其内部规划和结构。
-
MyBaseLayout:
- 这是 MyLayout 结构的根底类,一切详细的布局类(如
MyLinearLayout
、MyFrameLayout
等)都承继自它。它负责处理布局容器的根底功用,如视图的摆放、布局更新等。
- 这是 MyLayout 结构的根底类,一切详细的布局类(如
-
布局子类:
- 从
MyBaseLayout
派生的不同布局类型用于支撑多种布局办法:- MyLinearLayout:线性布局,视图顺次摆放,能够是笔直或水平。
- MyFrameLayout:帧布局,子视图堆叠在一起,依据设置的巨细、方位显现。
- MyRelativeLayout:相对布局,子视图能够相对于其他视图或容器进行布局。
- MyFlowLayout:流式布局,子视图按行或列摆放,相似于文本换行的作用。
- MyFloatLayout:起浮布局,视图能够依据容器空间主动摆放。
- MyPathLayout:途径布局,子视图能够沿着途径摆放。
- MyGridLayout:网格布局,子视图按网格摆放。
- MyTableLayout:表格布局,子视图按表格办法摆放。
- 从
-
MyViewSizeClass 和子类:
MyViewSizeClass
是用于界说视图在不同尺度类别下的体现,相似于 iOS 的 Size Class 概念。MyLayoutViewSizeClass
是它的子类,用于处理 MyLayout 视图的巨细、边距、方位等特点。- 不同的布局有各自的
ViewSizeClass
,如MyLinearLayoutViewSizeClass
、MyTableLayoutViewSizeClass
等,来界说在这些布局中的尺度规矩。
-
UIView 的扩展 (Category):
- 经过对
UIView
进行扩展,MyLayout 结构为视图增加了自界说布局特点,如leftPos
、topPos
、widthSize
、heightSize
等。这些特点与MyLayoutPos
和MyLayoutSize
类相关联,协助开发者经过简略的设置完结杂乱的布局需求。
- 经过对
-
MyLayoutPos 和 MyLayoutSize:
-
MyLayoutPos:MyLayoutPos类是用来描绘一个视图地点的方位的类。UIView中扩展出了leftPos,topPos,bottomPos,rightPos,centerXPos,centerYPos这六个变量来完结视图的定位操作。您能够用这些变量的equalTo办法来设置视图之间的边距和距离。 equalTo 办法能够设置NSNumber, MyLayoutPos, NSArray<MyLayoutPos*>这几种值,别离用于不同的场景。一起体系供给了6个简略的变量myLeft, myTop, myBottom, myRight, myCenterX, mYCenterY来设置NSNumber类型的值,比方 A.leftPos.equalTo(@10); 等价于 A.myLeft = 10;.
-
MyLayoutSize:MyLayoutSize类是用来描绘一个视图的尺度的类。UIView中扩展出了widthSize,heightSize这两个变量来完结视图的宽度和高度尺度的设置。您能够用其间的equalTo办法来设置视图的宽度和高度。equalTo办法能够设置NSNumber, MyLayoutSize, NSArray<MyLayoutSize*>这几种值,别离用于不同的场景。一起体系供给了2个简略的变量myWidth,myHeight来设置NSNumber类型的值,比方A.widthSize.equalTo(@10); 等价于A.myWidth = 10;.
-
-
MyWeight:
MyWeight
是一个与布局权重相关的概念,用于操控视图在容器中占有的相对空间。
经过这个类架构图,能够看到 MyLayout 结构是怎么经过承继和扩展的办法,将多种布局形式整合到一个结构中,然后简化杂乱布局的完结。
4. 底层原理
MyLayout 的底层原理首要是经过对每个视图的布局特点(如 myLeftMargin
、myWidth
、myHeight
等)进行核算,并在布局容器中依据这些特点从头调整每个子视图的方位和巨细。这个进程与 Auto Layout 体系相似,但 MyLayout 不依靠 iOS 自带的 Auto Layout 束缚机制,而是经过手动布局来优化功能和简化完结。
1. 视图树遍历与布局核算
MyLayout 的中心机制是遍历视图树,逐一核算每个视图的方位和巨细。这个进程在布局视图的 layoutSubviews
办法中触发。当父布局容器需求从头布局时,会调用 layoutSubviews
,在这个办法中,MyLayout 遍历一切子视图,并依据子视图的布局特点(如边距、宽高、自习惯等)进行核算和定位。
每个视图的布局特点都会影响到其终究的 frame
,MyLayout 会依据这些特点和布局容器的尺度来动态调整子视图的方位和巨细。例如:
myLeftMargin
和myRightMargin
决议视图在父视图中的左右距离。myWidth
决议视图的宽度,能够是固定值、百分比或依据内容自习惯。weight
特点用于动态分配剩下空间,相似于flexbox
的flex
特点。
2. 布局特点的自界说与扩展
MyLayout 依据 UIView 的扩展,将自界说的布局特点直接挂载在每个子视图上。经过为 UIView 扩展自界说特点(例如 myLeftMargin
、myHeight
),MyLayout 完结了布局特点的可拜访性。然后,结构经过在布局视图的 layoutSubviews
办法中拜访这些自界说特点,完结布局的核算和调整。
这些自界说特点的设定值能够是固定数值,也能够是相对父视图或兄弟视图的动态值,这使得 MyLayout 在布局时十分灵敏。例如:
- 当视图的宽度是相对父视图的宽度时,能够设置
myWidth.equalTo(self.view.myWidth)
,表明视图的宽度等于父视图宽度。
3. 自习惯与动态调整
MyLayout 支撑子视图的自习惯布局,经过核算视图的固有内容巨细和父视图的剩下空间,动态调整子视图的尺度和方位。与 Auto Layout 相似,当某个视图的内容发生变化时(例如文本视图内容变长),MyLayout 能够主动调整该视图的巨细,使其习惯新的内容。
此外,MyLayout 还支撑动态调整布局。当父视图的尺度改动时(例如旋转屏幕或窗口巨细调整),MyLayout 会从头核算一切子视图的布局,保证它们一直习惯当时的父视图巨细。
4. 防止 Auto Layout 的功能开支
MyLayout 的一个首要优势是防止了 Auto Layout 体系带来的功能开支。Auto Layout 经过束缚体系来办理布局,内部需求处理一系列的线性方程,这可能在杂乱布局场景下导致功能瓶颈。而 MyLayout 直接操作视图的 frame
特点,跳过了束缚的解析进程,然后提高了布局功率,特别是在需求频频动态调整布局的场景中体现更佳。
5. 布局类型的完结
MyLayout 供给了多种布局类型(线性布局、相对布局、表格布局等),这些布局类型的完结原理是依据布局容器的不同类型,选用不同的算法来核算子视图的摆放办法。例如:
- 线性布局:经过遍历子视图,依照笔直或水平方向顺次摆放,并依据
myLeftMargin
、myTopMargin
等特点调整每个视图的方位。 - 相对布局:依据子视图的相对定位特点(例如
centerXPos.equalTo()
),在布局时核算相对联系,调整视图的方位。 - 表格布局:依照队伍办法摆放子视图,相似于表格的布局逻辑。
6. 功能优化
MyLayout 的功能优化体现在以下几个方面:
- 防止不必要的重绘:在子视图的布局特点发生变化时,MyLayout 会触发布局改写,但它会防止无关子视图的重绘和布局调整,削减功能开支。
- 轻量级的布局核算:因为不依靠 Auto Layout 的束缚解析,MyLayout 的布局核算只触及简略的几许运算,防止了杂乱的束缚求解进程,然后提高布局功率。
- 支撑缓存机制:在某些杂乱场景下,MyLayout 还能够经过缓存布局成果,进一步削减重复核算的开支。
4. 运用
podfile中参加,然后运转,指令:pod install
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '7.0'
pod 'MyLayout'
结构作者还给出了一个y演示demo: