GitHub仓库:https://github.com/Jun2786184671/JUNFlex 记得给作者本人🌟
写在前面:
前些时间,本人实习的公司需要一个基于json实现ui可配置化的objc框架。但因当时本人技术储备有限,以及缺乏灵感等种种原因,很长一段时间未能想到如何较好地设计这个框架。后续接触了flutter和通过前端技术的学习,就想着能否用objc也实现类似的声明式ui编程,或者是一种基于objc的dsl。最后在两周前的周日下午,终于有了些想法,现在框架已经在测试环境下按预期工作了。。>_<
框架简述:
JUNFlex提供了以下几个组件实现快速的弹性布局:Hstack,Vstack,Zstack,Padding,Item,List。
1. 先介绍Item,它可以用来快速创建各种类型的view,比如:
- label
JUNFlex.item
.text(@"hello world", [UIFont systemFontOfSize:40], UIColor.blackColor)
.EOB; // End Of Build, 如果Item构建环境在Stack或Padding中,可以省略(后面会说到)
- image
JUNFlex.item
.size(250, 250)
.image(@"test-image.jpeg") // 参数也可以是一个URL
.EOB;
- button
JUNFlex.item
.width(80)
.height(44)
.radius(10)
.color(UIColor.whiteColor)
.border(3, UIColor.blueColor)
.text(@"Click me!",
[UIFont systemFontOfSize:30],
UIColor.blueColor)
.onTap(self, @selector(buttonOnClick:))
.EOB;
2. Hstack是一个横向布局,所有被它包裹住的view都会横向等距排列。
JUNFlex.hstack
.children(@[
JUNFlex.item
.height(30)
.color(UIColor.cyanColor)
.text(@"hello world",
[UIFont systemFontOfSize:20],
UIColor.blackColor),
JUNFlex.item
.size(100, 100)
.image(@"test-image.jpeg"),
JUNFlex.item
.width(80)
.height(44)
.radius(10)
.color(UIColor.whiteColor)
.border(3, UIColor.blueColor)
.text(@"Click me!",
[UIFont systemFontOfSize:16],
UIColor.blueColor)
.onTap(self, @selector(buttonOnClick:)),
]);
3. VStack与Hstack类似,对于所有的stack,你都可以指定它的对齐方式
⚠️ 对于Vstack,主轴是y轴,交叉轴是x轴。
对于Vstack和Hstack两个线性布局,
主轴:
< 0 最两侧间距相等 = 组件间距
= 0 最两侧间距相等 = 组件间距 * 0.5
> 0 最两侧间距相等 = 0
交叉轴
< 0 靠较小侧对齐
= 0 靠中间对齐
> 0 靠较大侧对齐
JUNFlex.vstack
.align(-1 /*主轴对齐方式*/, -1 /*交叉轴对齐方式*/)
.children(@[
JUNFlex.item
.width(100)
.color(UIColor.cyanColor)
.text(@"hello world", [UIFont systemFontOfSize:20], UIColor.blackColor),
JUNFlex.item
.size(100, 100)
.image(@"test-image.jpeg"),
[[UISwitch alloc] init], // 任何的UIView都能被加到stack的children里
]);
4. ZStack是堆叠布局,也可以指定对齐方式
JUNFlex.zstack
// .align(-1, -1) // 靠最左上方(坐标)对齐,默认为 (0, 0) 中心对齐
.children(@[
JUNFlex.item
.size(200, 200)
.image(@"test-image.jpeg"),
JUNFlex.item
.width(150)
.height(80)
.color(UIColor.cyanColor)
.text(@"hello world", [UIFont systemFontOfSize:30], UIColor.blackColor),
[[UISwitch alloc] init],
]);
5. Stack嵌套
JUNFlex.vstack
.align(-1, 0)
.children(@[
JUNFlex.hstack
.children(@[
JUNFlex.item
.height(30)
.color(UIColor.cyanColor)
.text(@"hello world", [UIFont systemFontOfSize:20], UIColor.blackColor),
JUNFlex.item
.size(100, 100)
.image(@"test-image.jpeg"),
JUNFlex.item
.width(80)
.height(44)
.radius(10)
.color(UIColor.whiteColor)
.border(3, UIColor.blueColor)
.text(@"Click me!", [UIFont systemFontOfSize:16], UIColor.blueColor)
.onTap(self, @selector(buttonOnClick:)),
]),
JUNFlex.zstack
.size(200, 200)
.align(-1, -1)
.children(@[
JUNFlex.item
.image(@"test-image.jpeg"),
JUNFlex.item
.width(150)
.height(80)
.color(UIColor.cyanColor)
.text(@"hello world", [UIFont systemFontOfSize:30], UIColor.blackColor),
[[UISwitch alloc] init],
]),
[[UISwitch alloc] init], // 任何的UIView都能被加到stack的children里
]);
6. Padding可以用来做那边距和装饰
JUNFlex.padding
.top(10).left(20).bottom(30).right(40)
.radius(20)
.color(UIColor.cyanColor)
.border(4, UIColor.blueColor)
.child( // 把需要被装饰的view包裹在child里
JUNFlex.item
.size(100, 100)
.image(@"test-image.jpeg")
);
7. List用于快速创建collectionview
JUNFlex.list
.size(500, 500)
// .horizontal(false)
.lineSpacing(20)
.count(100, ^id _Nonnull(NSUInteger i) { // 框架另外提供了多个可选的构造方法,如通过forEach构建
return
JUNFlex.zstack
.size(100, 100)
.children(@[
JUNFlex.padding
.radius(20)
.maskBounds(true)
.child(
JUNFlex.item
.alpha(0.6)
.image(@"test-image3.jpeg")
),
JUNFlex.vstack
.height(80)
.children(@[
JUNFlex.item
.text([NSString stringWithFormat:@"第%ld个", i],
[UIFont systemFontOfSize:20],
UIColor.blackColor),
JUNFlex.item
.text(@"Click me!", 18, UIColor.blueColor)
.onTap(self, @selector(buttonOnClick)),
]),
]);
});
8. JUNFlex可以使用json配置ui
{
"type" : "hstack",
"id" : "hello",
"border" : {
"width" : 10,
"color" : "orange",
},
"color" : "#00ffffff",
"radius" : "12.5",
"mask_bounds" : "true",
"align" : {
"main" : "center",
"cross" : "max",
},
"children" : [
{
"align" : {
"main" : "min",
"cross" : "center",
},
"size" : {
"width" : 100,
"height" : 200,
},
"color" : "red",
"text" : {
"string" : "hello",
"font" : {
"name" : "PingFang SC",
"size" : "20",
},
"color" : "purple",
},
"image" : "test-image.jpg",
},
{
"width" : 100,
"height" : 200,
"text" : "world",
"color" : "green",
},
{
"size" : {
"width" : 100,
"height" : 200,
},
"color" : "blue",
},
],
}
然后只需要在控制器中指定文件名就可以了
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.jun_layout(@"test.json");
}
提供了根据id查找view的方法
UIView *res = self.view.jun_query0(@"hello"); // 查找所有子视图中第一个匹配的结果
NSArray<UIView *> *resArray = self.view.jun_query(@"hello") // 查找所有匹配的结果
9. 后期会不断维护这个框架,有兴趣一起维护和改进的可以联系作者本人,欢迎star和fork我!!!
github: https://github.com/Jun2786184671
mail: maxinchun5@gmail.com