在swift中使用内联复合表达式

OC是C的超集html

在OC中,咱们能够使用一种名为内联复合表达式的语法 http://blog.sunnyxx.com/2014/08/02/objc-weird-code/express

利用这个特性,咱们能够在iOS开发中写复杂的页面布局时,作到相似HTML的标签化的语法.使布局结构和视图层级清晰明了.swift

举个例子:布局

有以下布局需求spa

布局示意图

HTML代码:.net

<div class="out">
    <div class="middle">
        <div class="inner">
            <p>content1</p>
        </div>
    </div>
    <div class="middle">
        <div class="inner">
            <p>content2</p>
        </div>
        <div class="inner">
            <p>content3</p>
        </div>
    </div>
</div>

能够看出,HTML代码的视图层级关系很是清晰.3d

使用OC代码布局,但不使用复合内联表达式的写法以下:code

    UIView *outContainer = [UIView new];
    [self.view addSubview:outContainer];
    [outContainer mas_makeConstraints:^(MASConstraintMaker *make) {
        //layout code
    }];
    
    UIView *midContainer1 = [UIView new];
    [outContainer addSubview:midContainer1];
    [midContainer1 mas_makeConstraints:^(MASConstraintMaker *make) {
        //layout code
    }];
    
    UILabel *textLabel1 = [UILabel new];
    [midContainer1 addSubview:textLabel1];
    [textLabel1 mas_makeConstraints:^(MASConstraintMaker *make) {
        //layout code
    }];
    
    UIView *midContainer2 = [UIView new];
    [outContainer addSubview:midContainer2];
    [midContainer2 mas_makeConstraints:^(MASConstraintMaker *make) {
        //layout code
    }];

    UILabel *textLabel2 = [UILabel new];
    [midContainer2 addSubview:textLabel2];
    [textLabel2 mas_makeConstraints:^(MASConstraintMaker *make) {
        //layout code
    }];

    UILabel *textLabel13 = [UILabel new];
    [midContainer2 addSubview:textLabel13];
    [textLabel13 mas_makeConstraints:^(MASConstraintMaker *make) {
        //layout code
    }];
    

虽然完成了布局,可是很不容易从代码看出视图的层级关系,往后维护的时候就不是很方便了.htm

改用复合内联表达式后的布局代码以下:blog

    UIView *outView = ({
        UIView *view = [UIView new];
        
        UIView *midView1 = ({
            UIView *view = [UIView new];
            
            UILabel *textLabel = ({
                UILabel *label = [UILabel new];
                //config your label
                label;
            });
            [view addSubview:textLabel];
            [textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                //layout code
            }];
            
            view;
        });
        [view addSubview:midView1];
        [midView1 mas_makeConstraints:^(MASConstraintMaker *make) {
            //layout code
        }];
        
        UIView *midView2 = ({
            UIView *view = [UIView new];
            
            UILabel *textLabel1 = ({
                UILabel *label = [UILabel new];
                //config your label
                label;
            });
            [view addSubview:textLabel1];
            [textLabel1 mas_makeConstraints:^(MASConstraintMaker *make) {
                //layout code
            }];
            
            UILabel *textLabel2 = ({
                UILabel *label = [UILabel new];
                //config your label
                label;
            });
            [view addSubview:textLabel2];
            [textLabel2 mas_makeConstraints:^(MASConstraintMaker *make) {
                //layout code
            }];
            
            view;
        });
        [view addSubview:midView2];
        [midView2 mas_makeConstraints:^(MASConstraintMaker *make) {
            //layout code
        }];
        
        view;
    });
    [self.view addSubview:outView];
    [outView mas_makeConstraints:^(MASConstraintMaker *make) {
        //layout code
    }];

能够看出层级关系清晰了.而且带来了额外的2个好处:

1.视图之间的耦合度下降了.此时能够复制任意一个内联表达式中包含的代码到其余位置,而不会引发布局错误.

2.不须要绞尽脑汁思考如何命名了,内联复合表达式中的命名由于做用域的关系没有冲突了.

 

而后咱们尝试在swift中也使用复合内联表达式

哦噢,报错了

这说明swift不支持复合内联表达式.bigView在swift中被编译器认为是一个代码块.

可是咱们又想使用这种语法带来的好处,怎么办呢?

咱们能够利用IIFE来模拟. http://weizhifeng.net/immediately-invoked-function-expression.html

        ({
            let view = UIView()
            contentView.addSubview(view)
            view.backgroundColor = .green
            view.snp.makeConstraints({ (m) in
                m.edges.equalTo(contentView).inset(UIEdgeInsetsMake(3, 3, 3, 3))
            })
            
            ({
                let label = UILabel()
                label.backgroundColor = .red
                label.textColor = .white
                self.label = label
                view.addSubview(label)
                label.snp.makeConstraints({ (m) in
                    m.center.equalTo(view)
                })
            })()
            
        })()

关键在于尾部的括号!

相关文章
相关标签/搜索