首页 > 其他分享 >iOS开发框架--MyLayout

iOS开发框架--MyLayout

时间:2024-10-20 11:20:38浏览次数:5  
标签:rootLayout MyLayout view1 -- equalTo 布局 iOS 视图

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 子视图。每个子视图都有自己的高度和边距设置。view1view2 分别设置了不同的高度,且左右边距为 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 的下方,并保持水平对齐。通过设置 centerXPostopPos 等属性,MyLayout 可以轻松实现相对布局。

3. 布局框架的类架构

这张图展示了 MyLayout 布局框架的类架构,帮助开发者理解其内部设计和结构。

  1. MyBaseLayout

    • 这是 MyLayout 框架的基础类,所有具体的布局类(如 MyLinearLayoutMyFrameLayout 等)都继承自它。它负责处理布局容器的基础功能,如视图的排列、布局更新等。
  2. 布局子类

    • MyBaseLayout 派生的不同布局类型用于支持多种布局方式:
      • MyLinearLayout:线性布局,视图依次排列,可以是垂直或水平。
      • MyFrameLayout:帧布局,子视图重叠在一起,根据设置的大小、位置显示。
      • MyRelativeLayout:相对布局,子视图可以相对于其他视图或容器进行布局。
      • MyFlowLayout:流式布局,子视图按行或列排列,类似于文本换行的效果。
      • MyFloatLayout:浮动布局,视图可以根据容器空间自动排列。
      • MyPathLayout:路径布局,子视图可以沿着路径排列。
      • MyGridLayout:网格布局,子视图按网格排列。
      • MyTableLayout:表格布局,子视图按表格形式排列。
  3. MyViewSizeClass 和子类:

    • MyViewSizeClass 是用于定义视图在不同尺寸类别下的表现,类似于 iOS 的 Size Class 概念。
    • MyLayoutViewSizeClass 是它的子类,用于处理 MyLayout 视图的大小、边距、位置等属性。
    • 不同的布局有各自的 ViewSizeClass,如 MyLinearLayoutViewSizeClassMyTableLayoutViewSizeClass 等,来定义在这些布局中的尺寸规则。
  4. UIView 的扩展 (Category)

    • 通过对 UIView 进行扩展,MyLayout 框架为视图添加了自定义布局属性,如 leftPostopPoswidthSizeheightSize 等。这些属性与 MyLayoutPosMyLayoutSize 类相关联,帮助开发者通过简单的设置实现复杂的布局需求。
  5. 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;.

  6. MyWeight

    • MyWeight 是一个与布局权重相关的概念,用于控制视图在容器中占据的相对空间。

通过这个类架构图,可以看到 MyLayout 框架是如何通过继承和扩展的方式,将多种布局模式整合到一个框架中,从而简化复杂布局的实现。

4. 底层原理

MyLayout 的底层原理主要是通过对每个视图的布局属性(如 myLeftMarginmyWidthmyHeight 等)进行计算,并在布局容器中根据这些属性重新调整每个子视图的位置和大小。这个过程与 Auto Layout 系统相似,但 MyLayout 不依赖 iOS 自带的 Auto Layout 约束机制,而是通过手动布局来优化性能和简化实现。

1. 视图树遍历与布局计算

MyLayout 的核心机制是遍历视图树,逐个计算每个视图的位置和大小。这个过程在布局视图的 layoutSubviews 方法中触发。当父布局容器需要重新布局时,会调用 layoutSubviews,在这个方法中,MyLayout 遍历所有子视图,并根据子视图的布局属性(如边距、宽高、自适应等)进行计算和定位。

每个视图的布局属性都会影响到其最终的 frame,MyLayout 会根据这些属性和布局容器的尺寸来动态调整子视图的位置和大小。例如:

  • myLeftMarginmyRightMargin 决定视图在父视图中的左右间距。
  • myWidth 决定视图的宽度,可以是固定值、百分比或根据内容自适应。
  • weight 属性用于动态分配剩余空间,类似于 flexboxflex 属性。
2. 布局属性的自定义与扩展

MyLayout 基于 UIView 的扩展,将自定义的布局属性直接挂载在每个子视图上。通过为 UIView 扩展自定义属性(例如 myLeftMarginmyHeight),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 提供了多种布局类型(线性布局、相对布局、表格布局等),这些布局类型的实现原理是根据布局容器的不同类型,采用不同的算法来计算子视图的排列方式。例如:

  • 线性布局:通过遍历子视图,按照垂直或水平方向依次排列,并根据 myLeftMarginmyTopMargin 等属性调整每个视图的位置。
  • 相对布局:根据子视图的相对定位属性(例如 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:

标签:rootLayout,MyLayout,view1,--,equalTo,布局,iOS,视图
From: https://www.cnblogs.com/jianqiu/p/18487045

相关文章

  • 一个比喻搞懂非对称加密
    【比喻前提】如果我们把用加密秘钥加密一个文件比喻为上锁,把用解密秘钥解密一个文件比喻为用钥匙开锁【比喻内容】那么对于一个敏感文件,对称加密的做法是把这个敏感文件上锁,并把钥匙给接收方。所以此时如果窃听者拿到了钥匙,就也可以阅读这个敏感文件。非对称加密的做法则......
  • 基于SpringBoot的甜品店管理系统(源码+LW+调试文档+讲解)
    一、背景介绍在现代社会,甜品店越来越受到人们的喜爱,成为人们休闲、聚会的好去处。然而,传统的甜品店管理方式往往存在效率低下、信息不透明、服务质量难以保证等问题。为了提高甜品店的管理水平和服务质量,开发一个基于SpringBoot+Vue的Web甜品店管理系统具有重要的现......
  • 基于微信小程序的社区订餐系统(源码+LW+调试文档+讲解)
    一、背景介绍随着生活节奏的加快和人们对便捷生活的追求,社区订餐服务的需求日益增长。传统的订餐方式存在诸多不便,如电话订餐容易出错、沟通效率低,线下订餐需要花费较多时间和精力。为了满足社区居民的订餐需求,提高订餐效率和服务质量,开发基于SpringBoot+Vue的X社区......
  • 如何分析 JVM 内存泄漏问题:常见原因、分析 JVM 内存泄漏的工具与步骤、如何避免 JVM
    文章目录1.JVM内存泄漏的常见原因2.分析JVM内存泄漏的工具与步骤2.1使用`jmap`工具生成堆转储文件2.2使用`jvisualvm`分析堆转储2.3使用EclipseMemoryAnalyzerTool(MAT)2.4监控GC日志2.5实时监控内存使用情况3.如何避免JVM内存泄漏4.总结5.相......
  • Vue CLI 与 Vite:构建工具的选择及其在 Vue 项目中的应用(如何在 Vue 2 中使用 Vue CLI
    文章目录1.引言2.VueCLI与Vite的基本概念2.1VueCLI概述2.2Vite概述3.如何在Vue2中使用VueCLI进行项目创建3.1安装VueCLI3.2创建Vue2项目3.3启动开发服务器4.Vue3项目中如何使用Vite实现快速开发4.1使用Vite初始化Vue3项目4.2启......
  • 微信小程序 基于uniapp的网络考试系统f8ya2
    目录项目介绍具体实现截图错误处理和异常处理设计方法和思路技术介绍小程序框架以及目录结构介绍java类核心代码部分展示其他uniapp小程序题目推荐详细视频演示源码获取项目介绍考虑到实际生活中在网络考试方面的需要以及对该系统认真的分析,将app权限按管理员,教师......
  • springboot+uinapp基于微信小程序个人健康管理小程序的设计与实现
    文章目录前言项目介绍技术介绍功能介绍核心代码数据库参考系统效果图文章目录前言文章底部名片,获取项目的完整演示视频,免费解答技术疑问项目介绍  当今社会已经步入了科学技术进步和经济社会快速发展的新时期,国际信息和学术交流也不断加强,计算机技术对经济社会......
  • 微信小程序 的旅游景点门票预订信息查询系统
    目录项目介绍具体实现截图错误处理和异常处理设计方法和思路技术介绍小程序框架以及目录结构介绍java类核心代码部分展示其他uniapp小程序题目推荐详细视频演示源码获取项目介绍旅游信息查询的需求和管理上的不断提升,旅游信息查询管理的潜力将无限扩大,基于安卓的旅......
  • 用C++实现自己的智能指针:深入探讨内存管理与RAII模式
    解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界C++中的内存管理一直以来是程序员的一个难点,尤其是在处理动态内存分配时。智能指针(如std::unique_ptr和std::shared_ptr)通过RAII(资源获取即初始化)的设计理念,极大地简化了动态内存的管理,减少了内存泄漏的风险。然......
  • 用C++编写一个简单的游戏引擎:从游戏循环到物理与渲染的全面解析
    解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界构建一个基础的2D游戏引擎是一项富有挑战性但极具学习价值的任务。本文将通过从零开始的方式,逐步讲解如何使用C++开发一个简单的游戏引擎。内容涵盖了游戏引擎的核心架构设计,包括游戏循环、物理引擎和图形渲染等......