Skip to content

lele8446/CJLayoutHelper

Repository files navigation

CJLayoutHelper简介

CJLayoutHelper通过读取特定数据结构的json数据,然后根据解析的数据使用Autolayout布局,自动绘制出所需要的页面视图。

CJLayoutHelper省去了通过Storyboard、xib或者代码绘制UI的步骤,使用配置数据来描述界面,理论上完全可以描绘出任意需要的UI页面。

对于已有的页面,使用CJLayoutHelper也可以随时调整页面布局。


CJLayoutHelper实现细节

*CJLayoutHelper绘制步骤如下:

  1. 根据每一个UI元素对应的不同json数据,计算出left、width、right、top、height、bottom的值(计算时如果是第一个子view其相对位置的视图取superView,其它view相对位置的视图取上一个子view);
  2. 判断viewType,运用runtime机制初始化出对应的view实例;
  3. 添加对应的Autolayout约束;
  4. 设置当前view的属性;
  5. 遍历subviews,重复1-4的步骤*

1. Autolayout下的UIView布局

Autolayout布局

如图所示,在Autolayout下,一个UIView能够被绘制需要满足以下约束条件:

  • 水平方向满足其中的一个条件:left+width、width+right、x+width、left+right
  • 垂直方向满足其中的一个条件:top+height、height+bottom、y+height、top+bottom

注意水平方向、垂直方向的约束条件不应该存在重复描述的情况,否则会有警告。约束冲突是可以通过设置约束优先级来解决的,现版本暂时未引入。另外框架暂时只处理了上述中,水平与垂直方向的8种约束条件,其它约束条件待扩展。

2. 页面布局与json数据结构

页面布局

分析页面UI,可以认为其是这样构成的: 页面元素以行为单位,从上往下、从左往右,从外往内绘制。 UIView是最外面的一行,其内部的子view是以垂直方向(vertical)布局的;
UIView1存在子view以水平方向(horizontal)布局;
UILabel1是UIView1的第一个子view;
UIScrollView是UIView1的第二个子view,其存在以水平方向布局的两个子view

对应的json数据结构图:

json数据结构

3. 单个UI元素的json数据结构

每一个UI元素对应一段特定的json数据,json数据由两部分构成:

  1. layout:用于描述页面布局,格式固定
  2. model: 用于描述当前view的一些属性
{ "viewStyleIdentifier": "scrollViewType",//配置文件对应的整体view的标识符,最外层view特有字段(最外层view时必填) "viewType": "UIView", //当前view的class,对应UIKit中的类型(必填) "leftPadding": 0, //水平方向左边的间距,对应Leading的值(默认0) "rightPadding": 0, //水平方向右边的间距,对应Trailing的值(默认0) "horizontallyAlignment": "leftWidth", //水平方向的布局位置,leftWidth、center、widthRight、leftRight(同级只有一个子view时才可设置)(默认leftWidth) "width": "1p", //宽度:0高度固定,宽度随文本内容动态变化; 0p~1p:数字加p表示取父view宽度的百分比;40表示=40 "topPadding": 0, //垂直方向上边的间距,对应Top的值(默认0) "bottomPadding": 0, //垂直方向下边的间距,对应Bottom的值(默认0) "verticalAlignment": "topHeight", //垂直方向的布局位置,topHeight、center、heightBottom、topBottom(同级只有一个子view时才可设置)(默认topHeight) "height": 44, //高度:0宽度固定,高度随文本内容动态变化; 0p~1p:数字加p表示取父view高度的百分比;44表示=44 "autolayoutHeight":true, //是否自动调整高度,当子view中包含高度未确定的元素时,值为true,默认false "layoutDirection":"vertical", //含有子view时,子view的布局方向,horizontally、vertical(默认horizontally水平布局) "subviews": [] //子view的model数组 }, "model":{    "backgroundColor": "#87CEEB",//背景颜色    "text": "标题",             //当前绘制的view的标题(如果存在的话)    "font": 14,                 //当前绘制的view的字体,默认取最底层superView的配置信息,如果都没有则默认为:[UIFont systemFontOfSize:14]    "textColor": "#000000"     //当前绘制的view的字体颜色,默认取最底层superView的配置信息,如果都没有则默认为:[UIColor blackColor] "idDescription": "CJUITextView_dz", //用来描述当前view的id,需要保证唯一性 "placeholder": "请输入地址" //默认提示 } } 

Objective-C调用

1. ConfigurationModel

数据建模类

/**  * 初始化model  *  * @param info  *  * @return   */ - (instancetype)initConfigurationModelInfo:(NSDictionary *)info;

2. CJLayoutHelper

  • CJLayoutHelperDelegate代理
    可以在代理回调中根据配置设置不同view的不同属性,比如字体大小、背景颜色、字体颜色等
@protocol CJLayoutHelperDelegate <NSObject> //配置回调 - (void)configureView:(UIView *)view withModelInfo:(NSDictionary *)info; @end
  • ViewStyleIdentifier
    ViewStyleIdentifier,描述当前配置文件对应的整体view的唯一标识符,在UITableView中可以将其作为UITableViewCell的Identifier
/** * 配置绘制的View的标识符(对应viewStyleIdentifier字段) * * @param info * * @return  */ + (NSString *)configurationViewStyleIdentifier:(ConfigurationModel *)info;
  • 获取高度以及初始化
/** * 获取所要绘制view的整体高度 * * @param info * @param contentViewWidth 绘制UI的父视图的宽度(比如:ScreenWidth) * @param contentViewHeight 绘制UI的父视图的高度(比如:ScreenHeight) * * @return */ - (CGFloat)viewHeightWithInfo:(ConfigurationModel *)info contentViewWidth:(CGFloat)contentViewWidth contentViewHeight:(CGFloat)contentViewHeight; /** * 根据配置文件初始化view * * @param info * @param layoutContentView 绘制UI的父视图(在哪个view上绘制) * @param contentViewWidth 绘制UI的父视图的宽度(比如:ScreenWidth) * @param contentViewHeight 绘制UI的父视图的高度(比如:ScreenHeight) * @param delegate 代理 */ - (void)initializeViewWithInfo:(ConfigurationModel *)info layoutContentView:(UIView *)layoutContentView contentViewWidth:(CGFloat)contentViewWidth contentViewHeight:(CGFloat)contentViewHeight                      delegate:(id<CJLayoutHelperDelegate>)delegate;

3. 其他

CJLayoutCategory中,添加了UIView+ConfigurationView分类,增加idDescription属性以及viewWithIdDescription:方法,可以通过idDescription获取指定view

@interface UIView (ConfigurationView) /**  * 自定义属性,用来描述view的id  */ @property (nonatomic, copy) NSString *_Nullable idDescription; /**  * 根据idDescription获取view,  * 可以是view本身,也可为nil  *  * @param idDescription view的id声明  *  * @return  */ - (nullable __kindof UIView *)viewWithIdDescription:(nullable NSString *)idDescription; @end

使用时直接将CJLayoutHelper文件夹添加到项目中即可,更多详情请参考demo

About

iOS动态界面布局框架

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published