之前如果做过Web前端页面的小伙伴们,看到绝对定位和相对定位并不陌生,并且使用起来也挺方便。在IOS的UI设计中也有绝对定位和相对定位,和我们的web前端的绝对定位和相对定位有所不同但又有相似之处。下面会结合两个小demo来学习一下我们IOS开发中UI的绝对定位和相对定位。在前面的博客中所用到的UI事例用的全是绝对定位,用我们Storyboard拖拽出来的控件全是绝对定位的,就是我们可以同改变组件的frame来改变组件的位置和大小。而相对定位则不同,相对定位是参考组件周围的元素来确定组件的大小或位置,相对定位即约束和周围组件的距离来布局的,即layoutConstraint. 在布局中LayoutConstraint和Fram布局方式是不能并存的。

上面说了这么多了,可能说的不太明白,还是那句话,怎么能少的了代码和实例的支持呢,下面会通过屏幕适配的事例来用绝对布局和相对布局同时实现下面的描述效果。

我们要实现的效果:当上面的view的大小及位置改变时,为了不覆盖掉下面的view,我们同时要改变下view的位置。 或者说在我们4.0寸正常显示的内容,在3.5寸屏上也能正常显示,即通常我们所说的屏幕的适配。为了便于观察效果,我们可以用Slider控件来动态的改变上面view的大小,观察下面view的位置变化,下面是我们要实现的效果图:

1.用绝对布局来实现上述效果,为了节省我们代码编写的时间,上面的控件是通过storyborad来实现的,然后在对应的ViewController里添加组件和控件回调的方法,主要是在slider滑动的时候来获取slider的值,然后动态的设置上面View的frame坐标(当然,如果让view往四周扩展得计算一下新的fram的值,然后动态的修改),上面的view位置和大小改变了,那么下面的view不能被上面的覆盖掉,所以也得修改blackView的fram的值。这种通过修改frame的值的方式来确定组件位置即为绝对布局

下面是由storyboard拖拽过来的属性:

1
2
3
4
5
6
//把最上边的view拖拽到我们的代码中
@property (strong, nonatomic) IBOutlet UIView *myView;
//添加slider
@property (strong, nonatomic) IBOutlet UISlider *mySlider;
//添加下面黑色的view
@property (strong, nonatomic) IBOutlet UIView *blackView;

下面是当slider的值改变时要回调的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//当slider的值改变的时候回调的方法
- (IBAction)sliderFunction:(id)sender
{
    //获取slider的当前值(在storyboard设置的范围为0-120)
    double value = self.mySlider.value;
 
    //获取myView的位置
    CGRect frame = self.myView.frame;
 
    //根据slider的值动态的设置myView的坐标和宽高,设置的时候view中心不变
    frame.origin.x =  120-value;
    frame.origin.y = 66 * (1-value/120);
    frame.size.height = 320-frame.origin.x*2;
    frame.size.width = 320-frame.origin.x*2;
 
    //更新myView的位置
    self.myView.frame = frame;
    //同时改变下面黑色view的坐标
    CGRect bf = self.blackView.frame;
    bf.origin.y = frame.size.height + frame.origin.y + 30;
    self.blackView.frame = bf;
 
}

2.上面是我们的绝对布局的方式,接下来要学习一下相对布局的方式。相对布局使用起来会比绝对布局要复杂一些,下面先做屏幕适配的例子,图一是在iPhone的4.0寸的效果图, 当我们不做任何处理的时候在3.5寸屏上是显示不出来的如第二张图:

(1)我们如何让在3.5寸屏上也显示正常呢,接下啦就是相对布局出出场的时候了,我们用相对布局的方式把最下面的view的位置改为相对于主视图的底部和左边的像素值固定,同时设置slider的位置相对于下面的view的位置相对固定。也就是下面的veiw的位置改变,则上面的slider的位置也会改变,用storyboard修改如下:(第一张图是修改最下面view的相对位置,第二张图是设置我们slider为相对布局) ,不需要在ViewController中添加任何动态吗我们就可以实现屏幕的适配。

(2)那么我如何用相对布局实现上面那种view放大的效果呢,接下来我们需要新建一个工程,因为相对布局和绝对布局在同一个组件中无法并存。在新建工程中用storyboard把我们用到的控件进行拖拽 ,界面和上面的是一样的。

(1)首先给我们最上面的View设置相对布局的属性,如下面的图一

(2)  再给黑色的View设置相对布局的属性,入下面的图二所示:

(3) 设置上面两个View相对中心对齐,选中上面的View,按着Ctrl往下面的View中拖拽,在弹出的框中选中Center X入图三

(4).给我们相应的组件在storyboard中添加上约束以后,怎样来动态的改变最上面view的宽和高的约束范围呢?(即改变水平约束和垂直约束的值)第一部就得把最上面的view的水平约束和垂直约束从我们的storyboard中把最上面View中我们要用的约束拖入到我们的Viewcontroller, 第一张图是storyboard中约束所在的位置,第二张图把约束添加到ViewController中。

          

​    ​    ​  (5)至此我们用storyboard的工作已经做完,程序员是少不了敲代码的,也只有正儿八经的敲代码,程序员才会成长。所以喽下面就是我们在ViewController中添加的代码部分。绝对布局直接改frame的坐标值就可以啦,那么在程序中我们如何去动态的改变我们约束的值呢?下面的代码将会用到。 我们要做的事情就是在ViewController中通过改变slider的值来改变最上面View的水平约束和垂直约束,水平约束和垂直约束的相关变量我们已经拖拽过来了,下面就需要在Slider回调的方法中来改变水平和垂直约束的值。先段代码,之后在说两句。    ​    ​

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
//slider的值改变调用的方法
- (IBAction)sliderChange:(id)sender
{
    //为了避免冲突移除myView的水平和垂直约束,注意是从主视图上移除,因为约束是加载我们的主视图上,即相对于我们的主视图
    [self.view removeConstraint:self.widthC];
    [self.view removeConstraint:self.heightC];
     
    //获取slider的值
    double sliderValue = self.mySlider.value;
     
    //由slider的值重设我们的约束值,H代表水平约束, V代表垂直约束
    NSString *widthValue = [NSString stringWithFormat:@"H:[_myView(%lf)]", sliderValue];
    NSString *heightValue = [NSString stringWithFormat:@"V:[_myView(%lf)]", sliderValue];
     
    //新建约束
    NSArray *widthConstraint = [NSLayoutConstraint constraintsWithVisualFormat:widthValue options:0 metrics:nil views:NSDictionaryOfVariableBindings(_myView)];
    //给水平约束重新赋值
    self.widthC = widthConstraint[0];
     
    //给垂直约束重新赋值
    NSArray * heightConstraint = [NSLayoutConstraint constraintsWithVisualFormat:heightValue options:0 metrics:nil views:NSDictionaryOfVariableBindings(_myView)];
    self.heightC = heightConstraint[0];
     
    //往主视图上添加新的约束
    [self.view addConstraint:self.widthC];
    [self.view addConstraint:self.heightC];
}

​    ​    ​代码说明:

​    ​    ​    ​    ​1.一个组件中只能有一中约束,如在myView中我们已经有一个垂直约束,我们如果再给他添加一个垂直约束的话,那么程序在运行时就会报错,错误内容:“Unable to simultaneously satisfy constraints.……”;

​    ​    ​    ​    ​2.所以在添加新的约束之前,我们得把之前加在我们组件中相应的约束给去掉;约束是加在我们对应组件的父视图上,移除也得从组件的父视图上移除;

​    ​    ​    ​    ​3.在设置约束的值的时候我们是以字符串的形式把参数传递给约束的,如:H:[_myView(200)] H代表水平约束,V代表垂直约束。中括号里是我们要为那个组件添加约束以及约束的值是多少;

​    ​    ​    ​    ​4.给我们的约束更新我们新建的约束;

​    ​    ​    ​    ​5.在把更新的约束添加到我们的父视图上,到此我们就可以实现上面我们上面用绝对布局实现的功能

​    ​    补充说明:

​    ​    ​    ​    ​在绝对布局时我们还可以获取屏幕的尺寸,通过屏幕的尺寸来计算我们组件所在的位置,主要代码如下:

1
2
3
4
5
6
//获取屏幕大小
UIScreen *s = [UIScreen mainScreen];
//获取屏幕边界
CGRect bounds = s.bounds;
//获取屏幕的高度
float height = bounds.size.height;

​    ​      上面的总结暂且这么说吧,是根据笔者自己的理解所总结的内容,不免有偏颇之处,欢迎批评指正,转载请注明出处。

IOS开发之绝对布局和相对布局(屏幕适配)的更多相关文章

  1. 01-02 Flutter仿京东商城项目 功能分析、底部导航Tab切换以及路由配置、架构搭建:(Flutter仿京东商城项目 首页布局以及不同终端屏幕适配方案)

    Flutter和Dart交流学习群:交流群:452892873 01Flutter仿京东商城项目 功能分析.底部导航Tab切换以及路由配置.架构搭建 02Flutter仿京东商城项目 首页布局以及不同 ...

  2. Android TV开发总结(五)TV上屏幕适配总结

    前言:前面几篇总结一些TV上的小Sample,开源到GitHub:https://github.com/hejunlin2013/TVSample, 点击链接,可以持续关注.今天总结下TV上屏幕适配. ...

  3. iOS开发之--Masonry多个平均布局

    使用Masonry平均布局,代码如下: 1.创建 // 图片组数 NSArray *imgAry = @[@"home_icon01",@"home_icon02&quo ...

  4. iOS开发之使用UIView-Positioning简化页面布局

    使用过代码布局的人可能会有这样的感觉,给控件设置frame的时候比较繁琐.最 近在Github上看到有一个UIView的一个分类UIView-Positioning,这个分类提供了一些属性,比如lef ...

  5. IOS开发之--iPhone XR,iPhone XS Max适配

    因为iPhone X和iPhone XS的尺寸比是一样的,只需要把这两张图片补上就行. 具体原理性的东西就多说了,因为iPhoneX系列都一样,本文只说明一下具体怎么做,要适配屏幕,首先得让他以正确的 ...

  6. ios开发3.5和4.0寸屏幕自适应中的一点问题

    在开发iso应用中需要考虑到ip4的3.5寸屏幕和ip5的4寸屏幕的高度不一样的问题.常见的问题有滚动条位置,底部被挡住等情况:我遇见是tableview中添加下拉上提刷新功能时刷新指示器显示位置的问 ...

  7. iOS -iPhone5、iPhone5s、iPhone6、iPhone6Plus 屏幕适配

    现在由于苹果公司出了6和6Plus,让写苹果程序的哥们为了做兼容很头疼.用StoryBoard固然方便,但是后期做兼容要花费太多的时间和精力.使用AutoLayout虽然会在不同尺寸的屏幕下自动布局, ...

  8. 1.[WP Developer体验Andriod开发]之Andriod布局 VS WinPhone布局

    0.写在前面的话 近来被HTML+CSS的布局折腾的死去活来,眼巴巴的看着CSS3中的flex,grid等更便捷更高效的的布局方式无法在项目中应用,心里那叫一个窝火啊,去你妹的兼容性,,, 最近体验下 ...

  9. 写给IOS开发工程师的网页前端入门笔记

    前言:作为IOS开发工程师,终会接触到网页前端开发,甚至可能会有 用HTML5开发IOS的app客户端的需求.比如现在上架的app就有比如理财类型的app有的就用HTML开发的,从理财类型的app需求 ...

  10. 1.[Andriod]之Andriod布局 VS WinPhone布局

    0.写在前面的话 近来被HTML+CSS的布局折腾的死去活来,眼巴巴的看着CSS3中的flex,grid等更便捷更高效的的布局方式无法在项目中应用,心里那叫一个窝火啊,去你妹的兼容性,,, 最近体验下 ...

随机推荐

  1. java基础知识小总结【转】

    java基础知识小总结 在一个独立的原始程序里,只能有一个 public 类,却可以有许多 non-public 类.此外,若是在一个 Java 程序中没有一个类是 public,那么该 Java 程 ...

  2. Android :fragment介绍

    一.关于Fragmemt 1.Fragment(片段),主要是为了支持更多的动态和灵活的用户界面设计,如平板电脑.Fragment允许组合和交换用户界面组件,而不需要更改视图层次结构.通过把Activ ...

  3. 递归一题总结(OJ P1117倒牛奶)

    题目:                    农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数,最初,A和B桶都是空的,而C桶是装满牛奶的.有时,约翰把牛奶从一个桶倒到另 ...

  4. centos上安装php运行环境

    可以参考,但我安装的过程不完全一样http://www.cnblogs.com/liulun/p/3535346.html 我先安装的apache,直接执行的yum -y install httpd ...

  5. 【http代理报文】通过发包实现代理请求网页内容

    工作中,我们难免需要通过TCP/IP协议发送报文来直接请求网页内容(比如爬虫工具),有同学问如何通过HTTP代理来请求网页,其实我们只需要把报文稍稍修改下,发送给代理服务器即可实现. 基础不过关的朋友 ...

  6. 工作总结_js

    工作至今已经有7个月了,虽然有进步,但是总感觉还是什么都不知道.可能这其中很大一部分还是与自己有关系,遇到自己不知道,问了人,或者百度到了,但是自己没有用心记.平时要用的时候,打开上一个项目,复制粘贴 ...

  7. 华为oj 刷题记录之合唱团

    华为OJ-合唱队 描述 计算最少出列多少位同学,使得剩下的同学排成合唱队形 说明: N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队 ...

  8. 【四】搭建Markdown的编辑器

    本系列有五篇:分别是 [一]Ubuntu14.04+Jekyll+Github Pages搭建静态博客:主要是安装方面 [二]jekyll 的使用 :主要是jekyll的配置 [三]Markdown+ ...

  9. 通过html和css做出下拉导航栏的效果

    通过观察了百度的首页,对于更多产品一栏,觉得可以不涉及JS便可写出下拉导航栏的效果 1.先设计出大体的框架 <div class="nav"> <ul> & ...

  10. SQL Server无法收缩日志文件 2 因为逻辑日志文件的总数不能少于 2问题

    SQL Server无法收缩日志文件 2 因为逻辑日志文件的总数不能少于 2问题 最近服务器执行收缩日志文件大小的job老是报错 我所用的一个批量收缩日志脚本 USE [master] GO /*** ...