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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容