xmarin 自动布局

以下文章前半部分节选自好友秋声赋的博客,虽然觉得说的很有道理,但是,我还没找到这个类库,不会用,在文章的下面我介绍一下我现在用的方式,来实现ios需要的自动布局,不管是4s,5s,6,6plus,横屏,甚至iPad都可以自动适应,当然我说这些话是白说!自适应当然所有屏幕都撑开了。哈哈

Xamarin.iOS 利用PureLayout进行代码布局(1)


一、iOS的布局方式

iOS算起来有2大类布局方式:

  • Storyboard、Xib的所见即所得的布局方式,两者没有太大的区别,Storyboard就是多个Xib的集合。这种方式与WPF很像,都是用Xml来描述界面,都是在编译时将Xml解析成代码。
  • 代码布局。这个就很常见了,我们在WPF和Winfrom里面经常会利用代码动态生成控件,再添加到视图中。

这个两种布局方法谁更好使在iOS编程的圈子里面争论了非常久,争论到现在也没有个结果。我推荐看下面这篇博客,这篇文章里面对两者的优劣说得很清楚了。

以下是我个人的意见,也是我写这篇文章的目的:
在Xamarin中特别是使用MVVM设计模式编写应用时我推荐使用代码布局,理由如下:

  • Storyboard与MVVM模式理念上有冲突,Storyboard不可避免的包含了一些视图逻辑,如页面跳转,这与MVVM模式视图不能具有复杂逻辑相冲突。
  • 不方便做版本控制,以及不利于模块化。Storyboard是用Xml格式描述的,虽然该Xml文件有一定的可读性,但是一般不会去手动修改,而且该Xml的每个元素有个Id是Guid严重依赖于当前工程。所以对Xml的版本控制和模块化没有太大意义。
  • VS和XS的Storyboard比较残疾,比较卡且少功能。我都是建议使用XCode的Interface Builder的,不过考虑到我们还是希望尽量在VS上编写代码所以只好用代码布局。

二、如何使用代码布局(AutoLayout与约束)

在iPhone6和6p到来后,iOS生态圈中分辨率的碎片化程度已经大大超过了Android,如果此时还使用Frame来进行硬编码布局只会让你痛不欲生。

苹果解决多分辨率适配问题的方法是使用AutoLayout。一种在使用上与WPF和Android完全不同的布局方式。在刚开始学习AutoLayout的时候会比较别扭,因为与你之前所学习的布局系统有非常大的区别。

总的来说我还是很喜欢iOS的AutoLayout的,感觉比WPF更适合移动终端这种界面不是很复杂的场合,特点如下:

  • 使用约束(constraints)来描述相同或者不同View的2个属性之间的关系。
  • 没有布局容器的概念,如WPF的Grid,StackPanel,Android的LinerLayout等等。
  • 接近人类的思维。
  • 有优先级的概念。

举一些约束的例子:

  • 这个蓝色的View在他的父视图的正中间。
  • 这个View的宽和高的比例为16:9。
  • 这2个View的高度相等。
  • 这2个View水平对齐。
  • 蓝色View的顶部距离红色View的底部2的像素。

从这可以看出约束本身非常符合人类本身的逻辑。 

关于约束我在这里就不展开讲了,网上很多教程与文章,这里推荐斯坦福大学的iOS公开课

三、优雅的使用AutoLayout(PureLayout)

如果你在代码中使用过官方的约束编写方式,肯定也比较痛苦,这里摘录一段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
UIView *superview = self;

UIView *view1 = [[UIView alloc] init];
view1.backgroundColor = [UIColor greenColor];
[superview addSubview:view1];

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[superview addConstraints:@[

//view1 constraints
[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:padding.top],

[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:padding.left],

[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-padding.bottom],

[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeRight
multiplier:1
constant:-padding.right],

]];

这端代码的含义是将view1放superview中,并且view1每个边离superview的每个边10像素。
是不是很复杂?说实话如果不是经常看约束的话很难一眼就看出这段代码具体实现的是什么效果。

来看看在PureLayout中如何实现这一效果:

1
2
3
4
5
var superView = this;
var view1 = new UIView();
superView.AddSubView(view1);

view1.AutoPinEdgesToSuperviewEdgesWithInsets(new UIEdgeInsets(10,10,10,10));

就是这么简单!短短一行代码就实现了上面一大段代码的效果,而且非常方便人理解,别人只要看一眼就知道你所要表达的效果。

四、iOS的原布局方式实现


在原有的布局基础上,每个view加上一段代
View.AutoresizingMask = UIViewAutoresizing.All;
这个方法置于有啥弊端我也不清楚,无疑加大了代码量,希望大家多多讨论,给我提点,谢谢!

猜你喜欢

转载自blog.csdn.net/qq_14840819/article/details/49076877
今日推荐