iOS开发笔记之七十三——基于状态机的页面构建方案

2023-10-22 11:59

本文主要是介绍iOS开发笔记之七十三——基于状态机的页面构建方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

******阅读完此文,大概需要20分钟******

一、简介

在美团点评时,页面基本都是列表页、详情页这类页面,所以以UIScollView/UITableView这类可以进行信息平铺的手段搭建页面为主。我之前也输出过这种页面的一种方案iOS开发笔记之六十四——基于UIView模块化组件方案_iOS开发笔记-CSDN博客,这种基于模块化,可以横向或者纵向平铺展示的方案还有很多。然而,原来的这种方案在Vivavideo这种工具类产品家族中,发挥的余地不是很理想。大家可以看下,这种工具类的一个典型的页面:

  

从上面的截图可以看出,工具类的这种编辑页下面有三种tab,每种tab下面又有很多的工具集合,如果你用传统的做法,无怪乎就是每种工具做一次addSubview,用到时做一次present的操作展示出来,你会发现,如果这样,你的VC会膨胀到你无法想象的地步。

    所以,在此基础上,我们探索出了一种状态机进行页面构建的方案,我们采取了GameplayKit中的GKStateMachine进行管理的,当然也可以自己做一套状态机进行管理。如果使用GKStateMachine去管理页面,是可以享受到它带给你一些便利的,例如以下几个操作:

- (BOOL)canEnterState:(Class)stateClass;

- (BOOL)enterState:(Class)stateClass;

以及GKState类的几种state生命周期的几个操作:

- (void)didEnterWithPreviousState:(nullable GKState *)previousState;

- (void)willExitWithNextState:(GKState *)nextState;

当你进入/退出一种状态时,都会有相应的回调;注意,这是iOS 9之后才有的。

在此基础上,我抽象出了一层基类,代码地址在这里,GitHub - Leon0206/MDStatePageKit: this is my statemachine page solution.,这只是1.0版本,后续还会不断迭代。

二、MDStatePageKit原理

1、树形结构管理状态机

每一个状态,犹如树形结构中的一个节点,它会有父状态、兄弟状态集合、子状态集合,如下图:

它有以下几个特征,

(1)一个状态有唯一的父状态(fatherState);

(2)一个状态可以有多个兄弟状态(brotherStates),兄弟状态之间可以随便切换;

(3)一个状态可以有多个子状态(childStates),父状态可以进入自己的子状态,子状态也可以返回父状态;

这些都已经体现在抽象出的基本状态单元类BaseViewState中:

@interface MDBaseViewState : GKState@property (nonatomic, strong) UIView *fatherView;@property (nonatomic, strong) UIView *contentView;@property (nonatomic, strong) GKState *fatherState;@property (nonatomic, strong) GKStateMachine *childStates;@property (nonatomic, strong) GKStateMachine *brotherStates;@end

每个状态都持有父状态的view,便于自己的contentView的布局与展示;

2、子状态的管理

当进入某一状态时(didEnterWithPreviousState:),才会去load它对应的子状态和兄弟状态;当离开某一状态时,此状态下的view也会被remove:

- (void)didEnterWithPreviousState:(MDBaseViewState *)preState
{NSLog(@"did enter the state: %@",self.name);[self.fatherView addSubview:self.contentView];[self loadChildStates];[self freeChildStates:preState];
}/*前一个状态节点的子状态以及contentView实时释放,从而可以及时释放部分内存,尽可能做到内存轻量化
*/
- (void)freeChildStates:(MDBaseViewState *)preState
{preState.childStates = nil;
}- (void)willExitWithNextState:(MDBaseViewState *)nextState
{NSLog(@"will exit the state: %@",self.name);[_contentView removeFromSuperview];_contentView = nil;
}

当然,使用者在这也可以去扩展

3、抽象基类BaseStateViewController对状态的管理

默认进入一个VC时,它是的父状态是空或者空状态(BaseZeroViewState),它的兄弟状态集合也是空(使用者可以自己扩展);

而它的子状态,需要使用者VC实现childViewStates方法,如下:

- (NSArray *)childViewStates
{return @[@"MDHopeZeroState",@"MDHopeFirstState",@"MDHopeSecondState",@"MDHopeThirdState",];
}

基类会在viewdidload时加载属于自己的子状态,与此同时,每个子状态之间又互为兄弟状态,所以每个子状态的兄弟状态也在此时进行了初始化,如下:

- (void)loadChildStates
{NSMutableArray *viewStates = [NSMutableArray array];for (NSString *obj in [self childViewStates]) {Class class = NSClassFromString(obj);if (!class) continue;MDBaseViewState *state = [[class alloc]init];state.fatherView = self.view;state.commonDataBoard = self.commonDataBoard;[viewStates addObject:state];}self.childStates = [GKStateMachine stateMachineWithStates:viewStates];//对于每种状态,它的子状态之间,互为兄弟状态for (MDBaseViewState *state in viewStates) {state.brotherStates = self.childStates;}
}

3、使用实例

下载GitHub - Leon0206/MDStatePageKit: this is my statemachine page solution.,运行里面的example,里面有一个完整的使用demo,MDStatePageKit还在不断完善中,有好的建议可以联系我634376133@qq.com。

这篇关于iOS开发笔记之七十三——基于状态机的页面构建方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/261303

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模