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