xamarin学习笔记B06(ios的Autolayout布局)

来源:互联网 发布:论坛模板源码 编辑:程序博客网 时间:2024/05/21 17:20

(每次学习一点xamarin就做个学习笔记和视频来加深记忆巩固知识)

如有不正确的地方,请帮我指正。

 

Autolayout简介

Autolayout是一种自动布局技术,很方便进行屏幕适配。在这之前有Autoresizing技术,但只能设置控件自己和父控件之间的位置关系,有点类似于Winform中的Anchor。而Autolayout可以设置任意控件之间的位置关系。

 

Autolayout原理

原理就是通过公式 View1.Property = (View2.Property * multiplier) + constant 最终得到Frame值(X,Y,Width,Height)。

视图1的属性值 = (视图2的属性值乘以乘数)加上一个常量值。

举几个例子:

例A:UIImageView的宽为150,高为150,距离UIView的左边和上边都是10。那么:

imageView.Width=(0 * 1.0)+150

imageView.Height=(0 * 1.0)+150

imageView.X=(UIView.Left*1.0)+10

imageView.Y=(UIView.Top*1.0)+10

 

例B:UILabel的上边距离图片是7,下边距离UIView是8,左边距离UIView是10,右边距离UIView的右边是16。那么:

label.Y=(imageView.Bottom*1.0)+7

label.Height=((UIView.Bottom*1.0-8) – label.Y

label.X=(UIView.Left*1.0)+10

label.Width=(UIView.Right*1.0-16) – label.X

 

例C:UILabel的宽永远等于UIView的宽的一半。那么:

label.Width=(UIView.Width*0.5)+0

Autolayout基本使用

例如要实现下图这样的布局:


条件如下:

1. 有三个控件,图片控件UIImageView,文本控件UILabel,和它俩的父控件灰色的UIView。

2. UIImageView的宽为150,高为150,距离UIView的左边和上边都是10。

3. UILabel的上边距离图片是7,下边距离UIView是8,左边距离UIView是10,右边距离UIView的右边是16,宽度则是跟随UIView的宽度自动变化,高度则跟随文本内容自动变化。

4. UIView距离屏幕的左和右都是20,宽度跟随屏幕宽度自动变化,高度则跟随它里面的子控件的高度自动变化,即刚好包住它们。距离屏幕上边暂时随变吧。

1. 通过界面设计工具来布局

首先查看storyboard的属性,默认是勾选了“UseAutoLayout”的。



还得注意要加如下代码//因为默认会有Autoresizing设置,所以要禁止IOS把默认的Autoresizing转成约束            grayView.TranslatesAutoresizingMaskIntoConstraints = false;            imageView.TranslatesAutoresizingMaskIntoConstraints = false;            label.TranslatesAutoresizingMaskIntoConstraints = false;

分别拖三个控件并调好大概的位置。第一步是切换到约束编辑模式,下图少了一个“模”字。第二步则进行相关拖线来设置约束。第三步在Layout栏可看到结果,可以点击设置图标来进行修改或删除约束。


在使用下面三个方式之前先做好准备工作,通过代码先添加好三个控件

//1.添加灰色View            UIView grayView2 = new UIView();            grayView2.BackgroundColor = UIColor.Gray;            grayView2.Frame = new CGRect(0, 400, 300, 300);            this.View.AddSubview(grayView2);            //2.添加图片View            UIImage image = UIImage.FromBundle("a1");            UIImageView imageView2 = new UIImageView(image);            imageView2.BackgroundColor = UIColor.Cyan;            imageView2.Frame = new CGRect(0, 0, 150, 150);            grayView2.AddSubview(imageView2);            //3.添加文本View            UILabel label2 = new UILabel();            label2.BackgroundColor = UIColor.White;            label2.Frame = new CGRect(5, imageView2.Frame.Size.Height + 7, 200, 20);            label2.Text = "BookName";            label2.Font = UIFont.SystemFontOfSize(UIFont.LabelFontSize, UIFontWeight.Bold);            label2.Lines = 0;//设置允许自动换行            grayView2.AddSubview(label2);            _label2 = label2; //默认会有Autoresizing设置,禁止IOS把默认的Autoresizing转成约束            grayView2.TranslatesAutoresizingMaskIntoConstraints = false;            imageView2.TranslatesAutoresizingMaskIntoConstraints = false;            label2.TranslatesAutoresizingMaskIntoConstraints = false;

2. 通过NSLayoutConstraint类来布局

直接上代码

//4添加grayView2的约束            //4.1添加X值约束            NSLayoutConstraint grayView2CT_X = NSLayoutConstraint.Create(grayView2, NSLayoutAttribute.Left, NSLayoutRelation.Equal                                                                         , this.View, NSLayoutAttribute.Left, 1.0F, 20);            this.View.AddConstraint(grayView2CT_X);            //4.2添加Y值约束            NSLayoutConstraint grayView2CT_Y = NSLayoutConstraint.Create(grayView2, NSLayoutAttribute.Top, NSLayoutRelation.Equal                                                                         , this.View, NSLayoutAttribute.Top, 1.0F, 300);            this.View.AddConstraint(grayView2CT_Y);            //4.3添加Width约束(因为有X值约束了,所以再来个Trailing就行了)            NSLayoutConstraint grayView2CT_Trailing = NSLayoutConstraint.Create(grayView2, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal                                                                                , this.View, NSLayoutAttribute.Trailing, 1.0F, -20);            this.View.AddConstraint(grayView2CT_Trailing);            //4.4添加Height约束            //不需添加高约束,因为可以根据里面的imageView和label自动计算出来            //5.添加imageView2的约束            //4.1添加X值约束            NSLayoutConstraint imageView2CT_X = NSLayoutConstraint.Create(imageView2, NSLayoutAttribute.Left, NSLayoutRelation.Equal                                                                        , imageView2.Superview, NSLayoutAttribute.Left, 1.0F, 10);            grayView2.AddConstraint(imageView2CT_X);            //5.2添加Y值约束            NSLayoutConstraint imageView2CT_Y = NSLayoutConstraint.Create(imageView2, NSLayoutAttribute.Top, NSLayoutRelation.Equal                                                                          , imageView2.Superview, NSLayoutAttribute.Top, 1.0F, 10);            grayView2.AddConstraint(imageView2CT_Y);            //5.3添加Width约束            NSLayoutConstraint imageView2CT_W = NSLayoutConstraint.Create(imageView2, NSLayoutAttribute.Width, NSLayoutRelation.Equal                                                                          , null, NSLayoutAttribute.NoAttribute, 1.0F, 150);            imageView2.AddConstraint(imageView2CT_W);            //5.4添加Height约束            NSLayoutConstraint imageView2CT_H = NSLayoutConstraint.Create(imageView2, NSLayoutAttribute.Height, NSLayoutRelation.Equal                                                                          , null, NSLayoutAttribute.NoAttribute, 1.0F, 150);            imageView2.AddConstraint(imageView2CT_H);            //6.添加label2的约束            //6.1添加X值约束            NSLayoutConstraint label2CT_X = NSLayoutConstraint.Create(label2, NSLayoutAttribute.Left, NSLayoutRelation.Equal                                                                      , label2.Superview, NSLayoutAttribute.Left, 1.0F, 10);            grayView2.AddConstraint(label2CT_X);            //6.2添加Y值约束            NSLayoutConstraint label2CT_Y = NSLayoutConstraint.Create(label2, NSLayoutAttribute.Top, NSLayoutRelation.Equal                                                                      , imageView2, NSLayoutAttribute.Bottom, 1.0F, 7);            grayView2.AddConstraint(label2CT_Y);            //6.3添加Width约束(因为有X值约束了,所以再来个Trailing就行了)            NSLayoutConstraint label2CT_Trailing = NSLayoutConstraint.Create(label2, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal                                                                             , label2.Superview, NSLayoutAttribute.Trailing, 1.0F, -16);            grayView2.AddConstraint(label2CT_Trailing);            //6.4添加Height约束所以再来个Bottom就行了(因为有Y值约束了,所以再来个Bottom就行了)            NSLayoutConstraint label2CT_Bottom = NSLayoutConstraint.Create(label2, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal                                                                           , label2.Superview, NSLayoutAttribute.Bottom, 1.0F, -8);            grayView2.AddConstraint(label2CT_Bottom);


3. 通过VFL(VisualFormatLanguage可视化格式语言)来布局

直接上代码。

NSDictionary viewDict = NSDictionary.FromObjectsAndKeys(new UIView[] { grayView2, imageView2, label2 },                                                                   new string[] { "grayView", "imageView", "label" });             string grayView2VFL_H = "H:|-20-[grayView]-20-|";//距父控件左边和右边都是20(X值和With值也就确定了)            string grayView2VFL_V = "V:|-350-[grayView]";  //距父控件上边是350,下边自动计算(Y值和Height值也就确定了)            NSLayoutConstraint[] grayView2VFLArray_H=NSLayoutConstraint.FromVisualFormat(grayView2VFL_H, 0                                                                                         , null, viewDict);            NSLayoutConstraint[] grayView2VFLArray_V =NSLayoutConstraint.FromVisualFormat(grayView2VFL_V,0                                                                                          ,null, viewDict);            this.View.AddConstraints(grayView2VFLArray_H);            this.View.AddConstraints(grayView2VFLArray_V);            string imageView2VFL_H = "H:|-10-[imageView(150)]";//距父控件左边为10,自已宽为150(X值和With值也就确定了)            string imageView2VFL_V = "V:|-10-[imageView(150)]";//距父控件上边是10,自已高为150(Y值和Height值也就确定了)            NSLayoutConstraint[] imageView2VFLArray_H =NSLayoutConstraint.FromVisualFormat(imageView2VFL_H, 0                                                                                         , null, viewDict);            NSLayoutConstraint[] imageView2VFLArray_V =NSLayoutConstraint.FromVisualFormat(imageView2VFL_V, 0                                                                                         , null, viewDict);            imageView2.Superview.AddConstraints(imageView2VFLArray_H);            imageView2.Superview.AddConstraints(imageView2VFLArray_V);            string label2VFL_H = "H:|-10-[label]-16-|";//距父控件左边为10,右边为16(X值和With值也就确定了)            string label2VFL_V = "V:[imageView]-7-[label]-8-|";//距上边(imageView)是7,下边(grayView)是8(Y值和Height值也就确定了)            NSLayoutConstraint[] label2VFLArray_H =NSLayoutConstraint.FromVisualFormat(label2VFL_H, 0                                                                                         , null, viewDict);            NSLayoutConstraint[] label2VFLArray_V =NSLayoutConstraint.FromVisualFormat(label2VFL_V, 0                                                                                         , null, viewDict);            label2.Superview.AddConstraints(label2VFLArray_H);            label2.Superview.AddConstraints(label2VFLArray_V);



4. 通过第三方开源框架Masonry来布局

从Nuget中下载安装Masonry这个包。

grayView2.MakeConstraints((ConstraintMaker obj) => {                obj.Left.EqualTo(this.View.Left()).Offset(20);                obj.Right.EqualTo(this.View.Right()).Offset(-20);                obj.Top.EqualTo(this.View.Top()).Offset(350);            });            imageView2.MakeConstraints((ConstraintMaker obj) => {                obj.Left.EqualTo(imageView2.Superview.Left()).Offset(10);                obj.Width.EqualTo(new NSNumber(150));                obj.Top.EqualTo(imageView2.Superview.Top()).Offset(10);                obj.Height.EqualTo(new NSNumber(150));            });            label2.MakeConstraints((ConstraintMaker obj) =>{                obj.Left.EqualTo(label2.Superview.Left()).Offset(10);                obj.Right.EqualTo(label2.Superview.Right()).Offset(-16);                obj.Top.EqualTo(imageView2.Bottom()).Offset(7);                obj.Bottom.EqualTo(label2.Superview.Bottom()).Offset(-8);            }); 


注意,最后记得注掉这三个控件的Frame代码。


Autolayout的约束的优先级

约束可以设置优先级,优先级高的生效。

例如有三个UIView,它们之间的水平间距都是10,当删掉中间青色的视图后,红色要自动贴到橙色的右边来且间距还是10。


上代码

//约束优先级            UIView orangeView = new UIView();            orangeView.BackgroundColor = UIColor.Orange;            UIView cyanView = new UIView();            cyanView.BackgroundColor = UIColor.Cyan;            UIView redView = new UIView();            redView.BackgroundColor = UIColor.Red;            this.View.AddSubview(orangeView);            this.View.AddSubview(cyanView);            this.View.AddSubview(redView);            _cyanView1 = cyanView;            orangeView.MakeConstraints((ConstraintMaker obj) => {                obj.Left.EqualTo(this.View.Left()).Offset(10);                obj.Bottom.EqualTo(this.View.Bottom()).Offset(-5);                obj.Width.EqualTo(new NSNumber(100));                obj.Height.EqualTo(new NSNumber(100));            });            cyanView.MakeConstraints((ConstraintMaker obj) => {                obj.Left.EqualTo(orangeView.Right()).Offset(10).Priority(260);                obj.Bottom.EqualTo(this.View.Bottom()).Offset(-5);                obj.Width.EqualTo(new NSNumber(100));                obj.Height.EqualTo(new NSNumber(100));            });            redView.MakeConstraints((ConstraintMaker obj) => {                obj.Left.EqualTo(cyanView.Right()).Offset(10);                obj.Bottom.EqualTo(this.View.Bottom()).Offset(-5);                obj.Width.EqualTo(new NSNumber(100));                obj.Height.EqualTo(new NSNumber(100));                obj.Left.EqualTo(orangeView.Right()).Offset(10).Priority(250);            }); public override void TouchesBegan(Foundation.NSSet touches, UIEvent evt)        {            base.TouchesBegan(touches, evt);            //label.Text = "BookNameBookNameBookNameBookNameBookNameBookNameBookNameBookName";            //_label2.Text = "BookNameBookNameBookNameBookNameBookNameBookNameBookNameBookName";            _cyanView1.RemoveFromSuperview();        } 

注意cyanView的Left约束的优先级

 obj.Left.EqualTo(orangeView.Right()).Offset(10).Priority(260);

和redView的Left约束的优先级

obj.Left.EqualTo(orangeView.Right()).Offset(10).Priority(250);

由于redView的优先级250低于cyanView的优先级260,所以开始显示出来不会生效,当删掉cyanView后,cyanView的约束也没了,所以redView约束中的第一句就失效了并且最后一句的就生效了。

结果如下图



代码和视频在我上传的CSDN资源中 http://download.csdn.net/download/junshangshui/10151330
原创粉丝点击