在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)
                })
            })()
            
        })()

關鍵在於尾部的括號!

相關文章
相關標籤/搜索