当前位置: 首页 > 编程日记 > 正文

iOS开发之绝对布局和相对布局(屏幕适配)

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

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

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

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

//把最上边的view拖拽到我们的代码中

@property (strong, nonatomic) IBOutlet UIView *myView;

//添加slider

@property (strong, nonatomic) IBOutlet UISlider *mySlider;

//添加下面黑色的view

@property (strong, nonatomic) IBOutlet UIView *blackView;

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

//当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回调的方法中来改变水平和垂直约束的值。

//当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;

}

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

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

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

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

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

补充说明:

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

//获取屏幕大小

UIScreen *s = [UIScreen mainScreen];

//获取屏幕边界

CGRect bounds = s.bounds;

//获取屏幕的高度

float height = bounds.size.height;

转载于:https://www.cnblogs.com/zhangz-1511/p/5042666.html

相关文章:

设计模式5-抽象工厂模式

package DesignPattern;public class AbstractFactory {public static class Dough{}public static class Sauce{}public static class Veggies{}public static class Cheese{}public static class Pepperoni{}public static class Clams{}//披萨public static abstract class …

wp打印输出日志

System.Diagnostics.Debug.WriteLine(String); 转载于:https://www.cnblogs.com/songtzu/archive/2012/07/26/2609678.html

Element-ui表格选中回显

先瞄一下&#xff0c;是不是你要的效果 然后&#xff0c;废话不多说&#xff0c;直接上代码啦 1 <template>2 <div class>3 <div class"projectData">4 <el-table :data"tableData2" ref"multipleTable" :show…

iOS开发者帐号申请指南

如果你是一个开发团队&#xff0c;在你打算掏腰包购买iOS开发者授权之前&#xff0c;最好先问一下你的同事&#xff0c;是否已经有人获得了开发许可&#xff0c;因为一个开发许可一年内最多可以授权给111个设备来开发测试。如果你没有授权许可可以借用&#xff0c;或者你打算最…

Redis的KEYS命令引起宕机事件

摘要&#xff1a; 使用 Redis 的开发者必看&#xff0c;吸取教训啊&#xff01; 原文&#xff1a;Redis 的 KEYS 命令引起 RDS 数据库雪崩&#xff0c;RDS 发生两次宕机&#xff0c;造成几百万的资金损失作者&#xff1a;陈浩翔Fundebug经授权转载&#xff0c;版权归原作者所有…

GridView的编辑,更新,取消,删除等功能演示

GridView的编辑,更新,取消,删除等功能演示 这是一个GridView应用的视频&#xff0c;内容很透彻的讲解了GridView的很多实用的技巧。 下载地址&#xff1a;http://download.cnblogs.com/insus/ASPDOTNET/GridViewEditUpdateCancelDelete.rar posted on 2015-12-15 09:20 代码养家…

mac 使用homebrew 安装mysql

1. 安装homebrew ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)" brew update 2.安装mysql brew install mysql 3.设置 MySQL 用户以及数据存放地址&#xff0c;下载的mysql的mysql_install_db文件中的路径有错误 需要重新设置一下文件路径&…

触控(Touch) 、 布局(Layout)

1 使用触控实现一个简易的画板 1.1 问题 触控&#xff08;Touch&#xff09;是一个UITouch类型的对象&#xff0c;当用户触摸了屏幕上的视图时自动被创建&#xff0c;通常使用触控实现绘图、涂鸦、手写等功能。本案例使用触控实现一个简易的画板&#xff0c;可以在画板上勾画出…

fail-fast和fail-safe的介绍和区别

2019独角兽企业重金招聘Python工程师标准>>> fail-fast和fail-safe 前言 前段时间公司招的实习生在使用迭代器遍历的时候,对集合内容进行了修改,从而抛出ConcurrentModificationException. 然后给他讲解之余也整理了这一篇文章. fail-fast ( 快速失败 ) 在使用迭代器…

hdu 4311 Meeting point-1

http://acm.hdu.edu.cn/showproblem.php?pid4311 思维呀 亲 你想到就可以做出来 想不到就做不出了 什么都不说了 上代码 不知道为什么 在hdu 上 long long 和 int 相乘就让我错 #include<iostream> #include<cstdio> #include<algorithm> #include<c…

Spring Boot 整合Pagehelper(为什么PageHelper分页不生效)

引入包https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter/1.2.10 <!--分页--><!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter --><dependency><groupId>com…

关于javascript的keycode

javascript event对象的具体功能是 event对象只在事件发生的过程中才有效&#xff08;比如鼠标点击&#xff0c;键盘按下等&#xff09;。event对象用以表示事件的状态&#xff0c;例如触发event对象的元素&#xff08;event.srcElement&#xff09;、鼠标的位置&#xff08;ev…

SQL-54 查找排除当前最大、最小salary之后的员工的平均工资avg_salary。

题目描述 查找排除当前最大、最小salary之后的员工的平均工资avg_salary。CREATE TABLE salaries ( emp_no int(11) NOT NULL,salary int(11) NOT NULL,from_date date NOT NULL,to_date date NOT NULL,PRIMARY KEY (emp_no,from_date));输出格式:avg_salary69462.5555555556SQ…

JqGridView 1.0.0.0发布

前几个月&#xff0c;客户要求显示列表做到列锁定表头锁定列组合,但从Extjs到Jquery EasyUi&#xff0c;从Jquery Grid到Telerik等等组件&#xff0c;发现无一符合条件&#xff0c;要么只能用列锁定&#xff0c;要么只能用列组合&#xff0c;当两者结合就不行了。于是只好开始自…

Struts2--ActionContext及CleanUP Filter

1. ActionContext ActionContext是被存放在当前线程中的&#xff0c;获取ActionContext也是从ThreadLocal中获取的。所以在执行拦截器、 action和result的过程中&#xff0c;由于他们都是在一个线程中按照顺序执行的&#xff0c;所以可以可以在任意时候在ThreadLocal中获取 Act…

HTML5跳转页面并传值以及localStorage的用法

1、首先&#xff0c;你得在那个页面把数据存入localStorage中吧。这个是必须的&#xff01; localStorage.setItem("user",JSON.stringify(data.allUser)); 用localStorage的setItem方法&#xff0c;这个方法看名字都知道得差不多了吧。。。setItem把数据存入localSt…

冒泡排序_python实现冒泡排序

冒泡排序是比较经典的面试题&#xff0c; 它重复地走访过要排序的元素列&#xff0c;依次比较两个相邻的元素&#xff0c;如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换&#xff0c;也就是说该元素列已经…

30分钟内让你明白正则表达式是什么,并对它有一些基本的了解(二)

测试正则表达式 如果你不觉得正则表达式很难读写的话&#xff0c;要么你是一个搞笑的天才&#xff0c;要么&#xff0c;你不是地球人。正则表达式的语法很令人头疼&#xff0c;即使对经常使用它的人来说也是如此。由于难于读写&#xff0c;容易出错&#xff0c;所以找一种工具对…

(区间dp 或 记忆化搜素 )Brackets -- POJ -- 2955

http://poj.org/problem?id2955 Description We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a regular brackets sequence,if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences…

[初级]深入理解乐观锁与悲观锁

2019独角兽企业重金招聘Python工程师标准>>> 在数据库的锁机制中介绍过&#xff0c;数据库管理系统&#xff08;DBMS&#xff09;中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。 乐观并发控制(乐观锁…

Umbra 3:次世代的遮挡裁剪

原文链接&#xff1a;http://www.gamasutra.com/view/feature/164660/sponsored_feature_next_generation_.php?print1 来自 Umbra Software [在这个主办方特辑中&#xff0c;Umbra Software讨论了当前使用的大量裁剪遮挡方法的优缺点&#xff0c;并解释了它自己的自动化遮挡…

在64位机上PLSQL连oracle11g问题:SQL*Net not properly installed和ORA-12154:TNS:无法处理服务名...

今天有同事在给客户安装我们的系统时&#xff0c;出现了问题。 背景&#xff1a;同事安装如下&#xff1a; 服务器是小机&#xff0c;在小机上做的虚拟机。WIN&#xff12;&#xff10;&#xff10;&#xff13;操作系统&#xff0c;装的是&#xff16;&#xff14;位的。 数据…

ios 应用和电脑共享文件夹_堪比AirDrop,苹果 iPhone与Windows电脑互传文件的三种方式...

如果你是苹果全家桶用户&#xff0c;一定会对 「AirDrop(隔空投送)」 功能赞誉有加&#xff0c;使用 AirDrop 可以在 iPhone 与 MacBook、iPad 等设备之间快速传递照片、视频或文件。遗憾的是&#xff0c;「AirDrop 仅限苹果设备之间使用」&#xff0c;而很多小伙伴应该和小兽一…

Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性

1 数组排序 1.1 问题 本案例实现一个整型数组排序的函数&#xff0c;数组排序的规则由传递的规则函数决定。 1.2 方案 首先定义一个整型数组排序函数sortInts&#xff0c;该函数有一个整型数组类型的参数&#xff0c;该参数必须是输入输出参数inout&#xff0c;否则并不能修改数…

shell命令之---Linux文件权限

本章内容  理解Linux的安全性 解读文件权限 使用Linux组 1、Linux的安全性---/etc/passwd文件 # cat /etc/passwdroot:x:0:0:root:/root:/bin/bash/etc/passwd文件的字段包含了如下信息&#xff1a; 登录用户名 用户密码 用户账户的UID&#xff08;数字形式&#x…

失败原因_解析干洗店失败原因

在市面上我们其实也知道有的店面开张时间不长或者最终没有存活下来&#xff0c;干洗店也不例外。我们在看到各地干洗店的高额利润的同时&#xff0c;也会发现一些失败的干洗店。他们的干洗店为何难以运营下去呢?下面伊斯曼小编来在多个方面剖析一下其中的蹊跷和缘由&#xff1…

seg:NLP之正向最大匹配分词

已迁移到我新博客,阅读体验更佳seg:NLP之正向最大匹配分词 完整代码实现放在我的github上:click me 一、任务要求 实现一个基于词典与规则的汉语自动分词系统。二、技术路线 采用正向最大匹配(FMM)方法对输入的中文语句进行分词&#xff0c;具体的实现可以分为下面几个步骤&…

喷涂机器人保养应该注意的七个事项

喷涂机器人又叫喷漆机器人(spray painting robot)&#xff0c; 是可进行自动喷漆或喷涂其他涂料的工业机器人。目前市面上采用比较多的品牌有ABB、库卡、发那科等等&#xff0c;长时间的使用能加速工业机器人的老化&#xff0c;保养是延缓机器人老化的一大关键&#xff0c;那么…

K均值与C均值区别

k均值聚类&#xff1a;---------一种硬聚类算法&#xff0c;隶属度只有两个取值0或1&#xff0c;提出的基本根据是“类内误差平方和最小化”准则&#xff1b;  模糊的c均值聚类算法&#xff1a;-------- 一种模糊聚类算法&#xff0c;是k均值聚类算法的推广形式&#xff0c;隶…

中超赛程来100wan点in_不干了:中超球队改名“硬重启”,球迷组织绝望解散

聚焦中超和CBA&#xff0c;独一无二球迷媒体点击右上角关注&#xff0c;你不会后悔的...2021赛季中超注定会与众不同&#xff0c;足协的新规将陆续实施&#xff0c;如果降薪还在外界意料之中的话&#xff0c;那么更改中性化名字的要求则让多数俱乐部较为头疼&#xff0c;尤其是…