您的位置:首页 > 移动开发 > Swift

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

2020-03-01 14:01 393 查看

OC是C的超集

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

利用这个特性,我们可以在iOS开发中写复杂的页面布局时,做到类似HTML的标签化的语法.使布局结构和视图层级清晰明了.

举个例子:

有如下布局需求

HTML代码:

<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代码的视图层级关系非常清晰.

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

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
}];

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

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

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

})()

关键在于尾部的括号!

 

转载于:https://www.cnblogs.com/ashamp/p/6890267.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
abc8864 发布了0 篇原创文章 · 获赞 0 · 访问量 782 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: