iOS之页面布局-踩坑的原由

iOS之页面布局

原文请点击

在《iOS 7 UI Transition Guide》中有在《iOS 7 UI Transition Guide》的Bar and Bar Buttons一节中有这么一段话

In iOS 7, the status bar is transparent, and other bars—that is, navigation bars, tab bars, toolbars, search bars, and scope bars—are translucent. As a general rule, you want to make sure that content fills the area behind the bars in your app.

翻译过来:

在iOS7中,状态栏是完全透明的,而其他bar,即navigation bars, tab bars, toolbars, search bars和scope bars都是半透明的。开发者需要保证页面内容能覆盖到这些bar的后面。

事实上,iOS7中的状态栏不仅变完全透明了,而且完全不占空间。
有码有真相 —— 新建一个UIViewController,再viewDidLoad里面输入以下代码,作为rootViewController启动应用:

- (void)viewDidLoad
{  [super  viewDidLoad];self.view.backgroundColor = [UIColor whiteColor];UILabel *label = [[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 200, 20)]autorelease];label.text = @"I am a label";[self.view addSubview:label];
}

应用效果:

Paste_Image.png

可以看到的是label和status bar悲催地重叠了。
我们再套一个UINavigationController,可以看到更悲催的事情:

Paste_Image.png

label活生生地被navigationBar盖住了。

可以说,苹果这次在iOS7上的redesign对开发者来说是惨绝人寰的。
不过苹果还是有节操的,在iOS7上运行iOS7 SDK以下开发的应用时,保留了原先的页面结构布局,并且做了不少向下兼容策略。
而且,iOS7 SDK提供了一系列接口和策略方案,下文将会一一介绍并顺带剖析一下iOS7上的页面结构框架。

Realtime Debug Protal
首先介绍一个小工具,可以方便我们进行学习。它的小名叫RDP,是一个类似Web Inspector的工具,把这个工具引入我们的项目工程,并做一些简单的配置,然后运行真机或者模拟器。应用启动后,在浏览器输入手机的IP地址,就可以看到UIView的树状结构和Log信息,还可以在浏览器中对View进行移动,隐藏,选中高亮等操作。

Paste_Image.png

状态栏
在iOS7中,状态栏是透明的,就是说,状态栏只有文字没有背景。
而变透明之后就很容易和后面的内容混淆,虽说一般应用不会把内容和状态栏叠合在一起,但是至少,现在的情况是,默认是会叠合的,开发需要从20px像素以下开始布局页面元素才能避免。

苹果为了让深色浅色背景均能让状态栏内容清晰显示,提供两种状态栏样式:

UIStatusBarStyleDefault = 0 黑色文字,浅色背景时使用
UIStatusBarStyleLightContent = 1 白色文字,深色背景时使用

而以下两个旧状态栏样式将被废弃:
UIStatusBarStyleBlackTranslucent = 1
UIStatusBarStyleLightContent = 2

还有,iOS7中我们通过ViewController重载方法返回枚举值的方法来控制状态栏的隐藏和样式。
首先,需要在Info.plist配置文件中,增加键:UIViewControllerBasedStatusBarAppearance,并设置为YES;
然后,在UIViewController子类中实现以下两个方法:

- (UIStatusBarStyle)preferredStatusBarStyle
{    return UIStatusBarStyleLightContent;
}- (BOOL)prefersStatusBarHidden
{return NO;
}

最后,在需要刷新状态栏样式的时候,调用[self setNeedsStatusBarAppearanceUpdate]方法即可刷新,若果需要以动画形式切换状态栏样式,则用以下方式调用即可:

[UIView animateWithDuration:0. animations:^{[self setNeedsStatusBarAppearanceUpdate];
}];

导航栏
在iOS7,由于状态栏背景透明,那么,导航栏背景就可能要兼职充当状态栏背景了。
iOS7默认导航栏样式就是这么做的,见下图:

Paste_Image.png

虽然用户看来,iOS7默认样式的状态栏和导航栏时连在一起的,但是实际上导航栏的位置和大小是和之前系统版本一样的,依然是贴在状态栏下面, 依然是高44px;之所以用户看来它们是连在一起,这是因为UINavigationBar里面的_UINavigationBarBackground 定位在y方向-20px的位置,然后高度增加到64px,这样就可以同时充当了两者的背景。

关于这些定位,苹果做了很多工作,后面也会谈到不少。不关心的同学可以略过,其实这些细节,个人觉得,即使对于开发者来说,也不是必需知道的,我们只需要知道怎么调用相关API就足够了。
实际情况下,我们会自定义导航栏背景,过去,我们也许会使用如下代码把一张高44像素(retina/88像素)的图片来平铺作为导航栏背景。

[navCtrl.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav_background"] forBarMetrics:UIBarMetricsDefault];

启动应用,出现了意想不到的效果和久违的界面 —— 黑底白字的状态栏,不再被navigationBar盖住的label。

Paste_Image.png

这里两个点需要解释一下:

  1. 若我们使用自定义图片作为导航栏的背景,那么UIViewController的view(下面称为视图)就不会延伸到navigationBar的顶部,而是从它的底部开始——正如往常一样。
  2. 若我们使用一张高44像素(retina/88像素)的图片作为导航栏背景,那么状态栏就会保持黑色,图片只会在导航栏区域平铺。

另外,iOS7 SDK中新增了一个设置背景图片的方法(setBackgroundImage:forBarPosition:barMetrics:),比原有的方法多了一个UIBarPosition枚举参数,用于设置背景图片拉伸的策略。
针对不同的拉伸设置和背景图片尺寸,在《iOS 7 UI Transition Guide》的Bar and Bar Buttons一节中
中有详细说明:

Paste_Image.png

 

页面布局
在 《iOS 7 UI Transition Guide》的Layout and Appearance 一节中也提到 —— 在iOS7中,view controllers使用全屏布局 (In iOS 7, view controllers use full-screen layout)。

通过上面的讨论我们也知道,除非导航栏设置了自定义的背景图片,否则每个视图都会延伸到屏幕一样大小的。
所以,像上面第二张图片中出现导航栏遮盖label的情况也是正常的现象。

如果我们要让label从导航栏以下位置显示,可以通过修改UIViewController的edgesForExtendedLayout这个属性来实现。
edgesForExtendedLayout是一个类型为UIExtendedEdge的属性,指定边缘要延伸的方向。
因为iOS7鼓励全屏布局,它的默认值很自然地是UIRectEdgeAll,四周边缘均延伸,就是说,如果即使视图中上有navigationBar,下有tabBar,那么视图仍会延伸覆盖到四周的区域。

如果把视图做如下设置,那么视图就不会延伸到这些bar的后面了,于是label又出来了。

self.edgesForExtendedLayout = UIExtendedEdgeNone;

Paste_Image.png

也许,这时候你会想,那为什么不把UIExtendedEdgeNone作为默认态呢?
iOS7以后鼓励全屏,它希望用户在使用可滚动视图的时候可以透过半透明的bar还可以看到一些模模糊糊的内容。

为了保持设计的优雅,同时避免给开发者太多的困扰,iOS7在Conttoller中新增了这个属性:automaticallyAdjustsScrollViewInsets,当设置为YES时(默认YES),如果视图里面存在唯一一个UIScrollView或其子类View,那么它会自动设置相应的内边距,这样可以让scroll占据整个视图,又不会让导航栏遮盖,如以下例子:

Paste_Image.png

要注意的是,这个例子中我们没有设置edgesForExtendedLayout,即视图是延伸至全屏的。
我们可以从UIView树状图看到,tableview的bounds值中有64像素的偏移值,它作为一个内边距来保持内容显示在导航栏以下,而滚动时仍可以透过半透明的导航栏看到模糊的内容。

最后一个介绍的新属性是extendedLayoutIncludesOpaqueBars,这个属性指定了当Bar使用了不透明图片时,视图是否延伸至Bar所在区域,默认值时NO。
所以我们如果自定义了导航栏的背景图片,那么视图会从导航栏以下开始,不会延伸到导航栏区域。
如果把这个属性设置为YES,那么视图将会延伸至导航栏区域,即使我们把导航栏设置成了自定义背景,如下图:

Paste_Image.png

视图延伸之后,label又被导航栏覆盖住了,正如我们意料。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247507.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工作中的javascript代码收集及整理

有个pub库放在blog的文件夹里面了,注意查查1.用javascript去除字符串左右空格,包括全角和半角//用javascript去除字符串左右空格,包括全角和半角String.prototype.trim function() { //其中表示为:对象.属性.方法函数方法var strTrim this.replace(/(^\s*)|(\s*$)/…

iOS11 更改状态栏、导航栏颜色的方法

ios上状态栏 就是指的最上面的20像素高的部分 状态栏分前后两部分,要分清这两个概念,后面会用到: 前景部分:就是指的显示电池、时间等部分; 背景部分:就是显示黑色或者图片的背景部分; (一)设…

i春秋DMZ大型靶场实验(四)Hash基础

下载工具包 打开目标机 通过目录爆破发现 phpmyadmin 在登录位置尝试注入 返现 可以注入 直接上sqlmap 上 bp 代理抓包 sqlmap.py -r bp.txt --dbs 利用sqlmap 跑出root 密码 root666888 登录 phpmyadmin t通过路径报错得到绝对路径 c:\\www\\1.php root 权限…

ASP.NET中进行消息处理(MSMQ) 二

在我上一篇文章《ASP.NET中进行消息处理(MSMQ)一》里对MSMQ做了个通俗的介绍,最后以发送普通文本消息和复杂的对象消息为例介绍了消息队列的使用。 本文在此基础上继续介绍MSMQ的相关知识点,最后还是通过一个示例程序来分析MSMQ在实际项目开发中的应用。…

GoJs Pictures 官方介绍文档

图片 使用Picture类显示图像。 最常见的用法是使用URL字符串设置Picture.source属性,以及通过GraphObject.desiredSize(图对象的所需尺寸)获取或通过设置GraphObject.width(图对象的宽)和GraphObject.height&#xff0…

怎样购买及安装ssl安全证书

查找资料记录,不是我的项目笔记 现在越来越多的网站都开始用安全链接了,在国外的话,如果不是一个安全链接,用户很大程度上会拒绝使用,所有安全链接是未来的趋势,楼主第一次配安全证书的时候,刚刚…

(转载)Git使用教程:最详细、最傻瓜、最浅显、真正手把手教!

转载自 Git使用教程 预警:因为详细,所以行文有些长,新手边看边操作效果出乎你的预料)一:Git是什么? Git是目前世界上最先进的分布式版本控制系统。 工作原理 / 流程: Workspace:工作…

soureTree中如何设置git 用户名与密码 SourceTree提交修改用户详细图文方法

mac上软件更新: 现在没有网络小模块了,在同行右边高级里面有默认用户名删除即可!!!! sourceTree 切换Git登录用户,之前在SourceTree提交远程服务用的是同事的账号,同事离职后账号也…

box-sizing的使用

box-sizing 人们慢慢的意识到传统的盒子模型不直接,所以他们新增了一个叫做 box-sizing 的CSS属性。当你设置一个元素为 box-sizing: border-box; 时,此元素的内边距和边框不再会增加它的宽度。这里有一个与前一页相同的例子,唯一的区别是两…

更新node最新版本方法和 npm install -g n 运行错误

使用xshell连接linux服务器后,首先输入node -v查看当前使用的版本 如果上面查看的版本比较低,则可以开始升级 清除npm cache 升级之前还需要安装n模块,n模块是专门用来管理nodejs的版本 输入npm install -g n n模块安装完成之后&#x…

Atom React或前端插件推荐

分享一些Atom个人在用的插件,喜欢请点赞 1. color-picker 取色工具 2. pigments 编辑器中直接查看代码所代表的颜色,工具虽小但是很实用。 3. minimap 仿sublime text的缩略代码查看,想找的地方一目了然。 4. highlight-selected 选择某段代码自动高…

Tapable.plugin is deprecated. Use new API on `.hooks` instead

问题描述 在使用extract-text-webpack-plugin给webpack打包时出现报错 Tapable.plugin is deprecated. Use new API on .hooks instead 1 问题原因 extract-text-webpack-plugin目前版本不支持webpack4。 解决方案 使用extract-text-webpack-plugin的最新的beta版 npm inst…

多重表(广义表)

在深入浅出数据结构系列前面的文章中&#xff0c;我们一直在讨论“线性表”&#xff0c;其形式如下&#xff1a; 由a1,a2,a3,……a(n-1)个元素组成的序列&#xff0c;其中每一个元素ai(0<i<n)都是一个“原子”&#xff0c;“原子”的意思就是说元素本身是一个个体&#x…

简单教你React父子组件间平级组件间传值

国庆充电特辑&#xff1a; 堵车堵死&#xff0c;废话不多说直接上菜。 1.父组件对子组件传值 利用props属性传值 class Component extends React.Component {constructor (props) {super(props);}render() {return (<div><h1>I am {this.props.name}</h1>…

Requests库的主要方法:requests.request为requests.get和requests.post两个的汇总,只是需要传方法...

1. requests.request(method,url,**kwargs&#xff09; method&#xff1a;请求方式&#xff0c;对应get/put/post等七种&#xff1a;拟获取页面的url链接&#xff1a;控制访问参数&#xff0c;共13个method&#xff1a;请求方式rrequests.request(GET,url,**kwargs) r reques…

jQuery插件开发教程

jQuery插件开发精品教程&#xff0c;让你的jQuery提升一个台阶 要说jQuery 最成功的地方&#xff0c;我认为是它的可扩展性吸引了众多开发者为其开发插件&#xff0c;从而建立起了一个生态系统。这好比大公司们争相做平台一样&#xff0c;得平台者得天下。苹果&#xff0c;微软…

微服务深入浅出(7)-- 网关路由Zuul

Zuul用于构建边界服务&#xff0c;致力于动态路由&#xff0c;过滤&#xff0c;监控&#xff0c;弹性伸缩和安全等方向。 1、ZuulRibbonEureka结合&#xff0c;可以实现智能路由和负载均衡 2、网关将所有服务的API接口统一聚合统一暴露 3、网关统一爆率接口后&#xff0c;可以做…

C# webkit内核 网页填表

比如我要操作的是下面的input 用到的方法是 调用如下&#xff1a; webkit.StringByEvaluatingJavaScriptFromString("document.getElementsByClassName(login_i_con_li_ipt name)[0].valueThis is a Demo."); 类似这种div在webkit中好像是无法通过常规方法模拟的 这时…

p字间距 html段落内文字设置字间距间隔

只对段落p内文字设置字间距&#xff0c;段落<p>是html段落标签&#xff0c;以<p>开始&#xff0c;以</p>结束&#xff0c;通常文章分段使用p标签&#xff0c;而有时小局部布局也可以使用p来布局。通过css设置其样式实现排版目的。 这里针对p设置字间距&…

基本数据类型

上节回顾 1.循环打印数列1&#xff0c;3&#xff0c;5&#xff0c;.........&#xff0c;99 for i in range(100):if i%21:print (i) 2.turtle 库 # penup 抬笔 # pendown 落笔 # pensize 画笔大小 # pencolor 画笔颜色## 画笔运动函数 # fd 前进 # bk 后退 # goto 到达指定的坐…