MyLayout 框架不仅支持 Objective-C,也可以在 Swift 中使用。通过 MyLayout,可以使用面向对象的方式来创建和管理视图的布局,简化了 Auto Layout 中繁琐的约束设置流程。在 Objective-C 中,MyLayout 提供了相同的布局类型和属性,使用方式稍有不同,主要是语法和调用方式上的差异。
先介绍一下如何使用吧,线性布局和相对布局是用的比较多的布局方式。
线性布局是一种里面的子视图按添加的顺序从上到下或者从左到右依次排列的单列(单行)布局视图,因此里面的子视图是通过添加的顺序建立约束和依赖关系的。 子视图从上到下依次排列的线性布局视图称为垂直线性布局视图,而子视图从左到右依次排列的线性布局视图则称为水平线性布局
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。
相对布局允许子视图通过相对父视图或者其他子视图的位置来布局。
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 可以轻松实现相对布局。
这张图展示了 MyLayout 布局框架的类架构,帮助开发者理解其内部设计和结构。

MyBaseLayout:
MyLinearLayout、MyFrameLayout 等)都继承自它。它负责处理布局容器的基础功能,如视图的排列、布局更新等。布局子类:
MyBaseLayout 派生的不同布局类型用于支持多种布局方式:
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
MyLayoutSize:MyLayoutSize类是用来描述一个视图的尺寸的类。UIView中扩展出了widthSize,heightSize这两个变量来实现视图的宽度和高度尺寸的设置。您可以用其中的equalTo方法来设置视图的宽度和高度。equalTo方法可以设置NSNumber, MyLayoutSize, NSArray
MyWeight:
MyWeight 是一个与布局权重相关的概念,用于控制视图在容器中占据的相对空间。通过这个类架构图,可以看到 MyLayout 框架是如何通过继承和扩展的方式,将多种布局模式整合到一个框架中,从而简化复杂布局的实现。
MyLayout 的底层原理主要是通过对每个视图的布局属性(如 myLeftMargin、myWidth、myHeight 等)进行计算,并在布局容器中根据这些属性重新调整每个子视图的位置和大小。这个过程与 Auto Layout 系统相似,但 MyLayout 不依赖 iOS 自带的 Auto Layout 约束机制,而是通过手动布局来优化性能和简化实现。
MyLayout 的核心机制是遍历视图树,逐个计算每个视图的位置和大小。这个过程在布局视图的 layoutSubviews 方法中触发。当父布局容器需要重新布局时,会调用 layoutSubviews,在这个方法中,MyLayout 遍历所有子视图,并根据子视图的布局属性(如边距、宽高、自适应等)进行计算和定位。
每个视图的布局属性都会影响到其最终的 frame,MyLayout 会根据这些属性和布局容器的尺寸来动态调整子视图的位置和大小。例如:
myLeftMargin 和 myRightMargin 决定视图在父视图中的左右间距。myWidth 决定视图的宽度,可以是固定值、百分比或根据内容自适应。weight 属性用于动态分配剩余空间,类似于 flexbox 的 flex 属性。MyLayout 基于 UIView 的扩展,将自定义的布局属性直接挂载在每个子视图上。通过为 UIView 扩展自定义属性(例如 myLeftMargin、myHeight),MyLayout 实现了布局属性的可访问性。然后,框架通过在布局视图的 layoutSubviews 方法中访问这些自定义属性,完成布局的计算和调整。
这些自定义属性的设定值可以是固定数值,也可以是相对父视图或兄弟视图的动态值,这使得 MyLayout 在布局时非常灵活。例如:
myWidth.equalTo(self.view.myWidth),表示视图的宽度等于父视图宽度。MyLayout 支持子视图的自适应布局,通过计算视图的固有内容大小和父视图的剩余空间,动态调整子视图的尺寸和位置。与 Auto Layout 类似,当某个视图的内容发生变化时(例如文本视图内容变长),MyLayout 可以自动调整该视图的大小,使其适应新的内容。
此外,MyLayout 还支持动态调整布局。当父视图的尺寸改变时(例如旋转屏幕或窗口大小调整),MyLayout 会重新计算所有子视图的布局,确保它们始终适应当前的父视图大小。
MyLayout 的一个主要优势是避免了 Auto Layout 系统带来的性能开销。Auto Layout 通过约束系统来管理布局,内部需要解决一系列的线性方程,这可能在复杂布局场景下导致性能瓶颈。而 MyLayout 直接操作视图的 frame 属性,跳过了约束的解析过程,从而提高了布局效率,特别是在需要频繁动态调整布局的场景中表现更佳。
MyLayout 提供了多种布局类型(线性布局、相对布局、表格布局等),这些布局类型的实现原理是根据布局容器的不同类型,采用不同的算法来计算子视图的排列方式。例如:
myLeftMargin、myTopMargin 等属性调整每个视图的位置。centerXPos.equalTo()),在布局时计算相对关系,调整视图的位置。MyLayout 的性能优化体现在以下几个方面:
podfile中加入,然后运行,命令:pod install
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '7.0'
pod 'MyLayout'
框架作者还给出了一个y演示demo:

登录查看全部
参与评论
手机查看
返回顶部