JUNFlex,基于Objective-C实现快速布局的UI框架,iOS开发

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中,可以省略(后面会说到)
Simulator Screen Shot - iPhone 14 Pro - 2022-12-10 at 00.04.49.png
  • image
JUNFlex.item
.size(250, 250)
.image(@"test-image.jpeg")  // 参数也可以是一个URL
.EOB;
Simulator Screen Shot - iPhone 14 Pro - 2022-12-10 at 00.01.09.png
  • 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;
Simulator Screen Shot - iPhone 14 Pro - 2022-12-09 at 23.54.54.png
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:)),
]);
Simulator Screen Shot - iPhone 14 Pro - 2022-12-10 at 00.13.49.png
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里
]);
Simulator Screen Shot - iPhone 14 Pro - 2022-12-10 at 00.30.48.png
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],
]);
Simulator Screen Shot - iPhone 14 Pro - 2022-12-10 at 00.52.52.png
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里
]);
Simulator Screen Shot - iPhone 14 Pro - 2022-12-10 at 01.01.19.png
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")
);
Simulator Screen Shot - iPhone 14 Pro - 2022-12-10 at 14.51.31.png
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)),
        ]),
    ]);
});
Simulator Screen Shot - iPhone 14 Pro - 2022-12-10 at 15.07.43.png
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");
}
Simulator Screen Shot - iPhone 14 Pro - 2022-12-10 at 15.22.27.png

提供了根据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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容