iOS-raywenderlich翻译-如何升级程序以适应4英寸的iPhone5显示

注:本文由BeyondVincent(破船)翻译首发

        转载请注明出处:http://blog.csdn.net/beyondvincent


13 MARCH 2013

本文是由 iOS Tutorial 小组成员 Adam Burkepile撰写,他是一名全职的软件咨询师和iOS独立开发者。 这里可以看到他最近开发的程序: Pocket No Agenda, 还可以在 Twitterfollow他。

iPhone 5配备了更大的屏幕——你的程序有更多的使用空间:额外增加了88点(176像素)。

不过这跟之前的Retina显示屏一样,你需要对程序做一些修改,以利用更大的屏幕带来的好处。

很幸运的是很容易就能够利用上新的屏幕尺寸。然后稍微做一些设计,你的程序就可以用有趣的方式使用新增的空间。

如果你的程序还没有更新至适配新的4英寸屏幕,那么通过本文,你就可以很容的进行适配并提升你的应用体验!

入门

首先,你的Xcode版本需要支持iPhone 5的开发——也就是Xcode版本至少是4.5。通过这样的操作你可以查看Xcode的版本: Xcode\About Xcode. 如果你的版本早于4.5,那么需要到Mac App Store下载或者升级到最新版本。

注意:Xcode 4.5中,苹果放弃了对armv6指令集的支持。也就意味着你用Xcode 4.5以及更新的版本创建的程序,将不能在最初的iPhone,iPhone 3G,或者第一代iPod Touch和第二代iPod Touch上运行了。

我使用的本文的工程代码:如果你是这个网站的忠实读者,那么可能你以及下载过了—— How to Use Blocks in iOS 5 – 我在这个网站写的第一篇文章!

虽然Ray的妻子Vicki为这个iOS Diner项目创建出了非常可爱的画面,但是为了将这些画面放适当的屏幕中,这闲得太拥挤——从来没有让我舒服过。现在本文介绍的内容是个非常好的机会来解决这个问题。

从以前的教程中下载完整的工程代码(修改了一些bug): here .

打开工程文件,然后立马编译并运行它。确保运行在 iPhone 6.1 模拟器中, 因为所有的iPhone 5s都将至少运行在iOS 6中。如果程序没有运行在 iPhone 5 4-inch 模拟器中, 那么在Hardware菜单中的Device里面,修改一下。接着再编译运行程序。如下图所示:

BOOM! iPhone 5 Simulator 是个4英寸的家伙!

iPhone 4 Inch Screen with Wasted Space

Oh,稍等。在模拟器两边难看的黑边(红色圆圈标注)是什么东西?这是由于你的程序还没有对iPhone 5适配。现在你需要对其进行修改!

Hey, 你获得了更多的空间!

实际上让你的程序兼容4英寸的屏幕非常简单。

如果之前你一直在做相关的适配工作,并设置过启动画面,那么现在你应该有这样的两个图片: Default.png 和 Default@2x.png. 现在针对启动画面你所需要做的就是添加一个名为 Default–568h@2x.png 的启动图片! 因为所有4英寸的屏幕都是retina,所你这里不需要相应的non-@2x 版本图片。很简单,不是吗?

这里现在这个新的启动图(this new launch image )名字叫做 Default–568h@2x.png 并将其拖拽到工程中,如下图操作所示.

编译并运行程序.

首先,程序加载过程中是正确的 — 一个大的启动图片:

但是后来呢…

嗯, 画面并没有完全自动的与屏幕尺寸匹配上。从上图,可以看到你还有多少屏幕没有利用上, 现在你必须要做一点处理,让其与屏幕相适配。

出现上图中的这个原因是因为当初为这个程序所做的设计是针对通用屏幕尺寸的。并没有使用自动调整大小(autosizing),自动布局(Auto Layout),或者其它一些技术,现在就来修正一下这个问题吧!

使用约束(Constraints)

这里有几种不同的方法可以根据不同的屏幕尺寸对视图大小进行调整。在本文中,我将使用iOS 6中引入的新技术: Auto Layout system . 通过Auto Layout,可以把view固定到边缘上,并可以把view设置为自动扩大或者缩小。

注意: 本文只涉及到Auto Layout中的初级知识。相关更深入的知识,可以查看本网站上iOS 6系列文章:Beginning Auto Layout . 这里的链接可以看到第一部分: here.

首先,开启 Auto Layout. 必须在每个storyboard中都要进行开启Auto Layout功能。

在本工程中,只有一个名为storyboardMainStoryboard.storyboard的文件。选中这个文件,然后打开file inspector,并勾选上 Use Autolayout, 如下图.

现在,在Diner程序的用户界面中,注意到向右的这个箭头,它的作用是让用户可以选择可用项中的下一项。

Right facing arrow problems with Auto Layout

当frame变得更大时,这个向右的箭头看起来是固定到右边缘的. 现在来对这个箭头做一些修改,让它与别的view一样,固定到左边缘上。

选中这个右箭头,然后选择Size Inspector. 可以看到view中已有的Auto Layout相关的约束。

在storyboard画布底部 ,选择这样一个外形切换按钮图标 (看起来有点像横着的 “I”) ,然后选择Leading Space to Superview, 如下图所示.

现在马上就可以看到新选择的约束。

在不需要重新编译并生成整个工程的情况下,就可以通过在storyboard中修改屏幕尺寸来测试这个约束在4英寸屏幕上的效果。修改屏幕尺寸的操作可以这样:菜单中,选择 Editor\Apply Retina 4 Form Factor, 也可以通过选择画布底部的这个外形尺寸按钮(这个按钮是一个矩形框,顶部和底部分别有一个箭头),如下图。

嗯, 如下图,看起来有点跟预期的不一样!重新选择右箭头和Size Inspector ,并查看是什么原因。

哇, 如上图右边,现在这个右箭头有3个约束了。一个是与顶部其它的按钮对齐,这是正确的。还有一个是刚刚添加的。

但是中间这个:Trailing Space to: Superview, 这是将这个箭头按钮的右边固定到父视图(superview)的右边。因此,结合新的约束是固定到左边,而旧的约束是固定到右边,这样的话当屏幕增大的时候,Auto Layout除了将这个按钮拉伸,就没有别的选择了。!

要修正这个问题很容易,不过在做任何操作之前,确定切回到更小的屏幕尺寸,否则将不会像预期的一样正常工作。(要明白为什么,请看下面的注意部分。)

切回到更小的屏幕尺寸之后,选中 Trailing Space to: Superview 约束的齿轮图标,然后选择 Delete. 这里不再需要将右箭头按钮固定到superview的右边。

当你再切回到大屏幕尺寸时,图片看起来是下面这样:

嗯, 现在好多了.

为什么要切回到更小的屏幕尺寸? 如果在显示大屏幕内容时,删除约束,Xcode会添加新的宽度约束,以强制右箭头跟以前一样是拉伸的。因此要避免这个问题,你需要分别对待两种屏幕尺寸!

出现上面这种情况,是因为当Auto Layout开启时,你对view或者约束做任何的修改,都会引起Xcode重新计算出当前的约束内容。Xcode为了在当前屏幕尺寸中正确显示视图,总是会默认的添加相关约束。所以,当箭头处于拉伸状态时,如果你删除了这个约束,Xcoe会添加另外一个约束,以让这个箭头保持拉伸状态。

这就是为什么在结合使用Auto Layout时,你会经常看到一些你不想看到的一些约束。当发生这种情况时,简单的将其删除是不行的,因为Xcode会再次添加约束。相反,你需要创建不同的约束,直到Xcode认为你删除的这个约束不再需要。

难以执行的伸缩Diner

现在,你需要对diner本身进行拉伸 - 包括背景和计数图片。

切回更小的屏幕尺寸 然后同时选中背景和计数视图: 分别是Image View – bg_wall.png 和 Image View – bg_counter.png. 它们已经有约束了,当屏幕增大时,这些视图会被拉伸。下面我们再来选中pin图标…

添加 Trailing Space to Superview 约束,如下图所示…

然后再点击外形切换按钮,来看看具体效果.

如上图,背景图片如预期的一样被扩大了,但是图片不够大,所以被居中显示了。当程序运行在4英寸的屏幕上时,你需要修改图片,但是这里没有这样的一种机制:“针对3.5英寸屏幕使用这个图片,而针对4英寸屏幕则使用别的图片”。因此,在这里需要通过编写代码进行处理。

在storyboard中,打开assistant view,通过control-drag counter和background UIView来创建IBoutlets,名字分别为 ibCounter 和 ibBackgroundImage.

接下来,在Supporting Files 群组中选择 iOSDiner-Prefix.pch 文件,并在底部的#endif 上面添加如下代码 (归功于StackOverflow):

#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)

通过上面这行代码你可以知道程序现在是否运行在大尺寸屏幕中。代码实际上就是通过当前屏幕的尺寸,减去iPhone 5的屏幕尺寸,如果结果是0,那么说明设备是iPhone 5。

下面在 IODViewController.m文件中使用这个宏。 将如下代码添加到viewWillAppear:最后:

if (IS_IPHONE5) {
    self.ibBackgroundImage.image = [UIImage imageNamed:@"bg_wall-568h.png"];
    self.ibCounter.image = [UIImage imageNamed:@"bg_counter-568h.png"];
}

上面的代码首先检查当前程序是否运行在iPhone 5上(大屏幕);如果是的话,设置一个新的,大版本的图片。这里的图片已经存在于之前下载的starter工程中了。

在这里,可能你要问“不应该是bg_wall–568h@2x.png吗?嗯, 不是的. 请记住UIImage会自动的添加“@2x” 来寻找针对retina的图片。因此即使你工程中包含的是 bg_wall–568h@2x.png 图片, 最终选择使用图片时也不需要@“2x”。

编译并运行程序,效果如下图所示:

移开点,你挤到我了!

现在,程序有一个更大的背景了,但是右边的空间还是没有利用上。而这时,所有的东西都挤在左边了。下面就来对收银员位置重新定位一下,以利用额外的空间。

跟之前一样,确保使用3.5英寸的外形尺寸来编辑storyboard。现在选中Bill(视图的名字是 Image View – person.png) ,并添加一个新的 Trailing Space to SuperView pin 约束.

跟右箭头一样,Bill已经有一个Leading 约束了, 所以,如果现在切到4英寸的屏幕上,Bill将被拉伸。你知道的,Bill虽然是工作在一个快餐厅,但是他并没有那么胖!选中 Leading Space to: Image View 约束并将其删除掉。

再次切换一下外形尺寸.

非常棒!Bill现在被固定到右边,并利用上了更大的屏幕空间了。

注意: 描述区域(如上图现在是“Hamburger”)同样被固定到右边了。但是你并没有对其进行修改呀。这是怎么发生的呢?

这是因为这个图片被固定到文本标签上,而这个文本标签是被固定到Bill图片上的。因此当Bill的位置发生改变时,也会对描述文本控件和图片进行更新。Cool,不是吗?

等等… Auto Layout必须在iOS 6 中吗?

现在如果你将这个iOS Diner程序运行在iPhone5.1 Simulator上,程序在启动的时候就会crash(奔溃)掉,实际上, 实际上,只要你在storyboard上开启Auto Layout,那么就会发生这个错误。这也是为什么Auto Layout必须要在iOS 6中才支持。

对于这个程序可能不是一个大问题,因为此时大约有87%的用户已经在使用iOS 6了( are using iOS 6),但是需要知道这点。

当你发布一个程序时,你需要决定程序将支持iOS最低的版本。针对全新的程序,你可能希望选择iOS 6,但是在本文中,是对已有的程序进行升级。如果你提高了支持的最低版本,可能当前的用户并没有升级到最新的iOS版本,那么就会遇到问题哦。

通常,你有两个选择:

  1. 你可以修改工程的部署目标(deployment target),指定你的程序运行所需要的iOS版本。
  2. 你可以让你的程序向后兼容。

下面我将对这两个选择都进行介绍。在本文中,你也可以只做一个,当然两个也行 — 如果你愿意的话,也可以忽略掉本节的全部内容!

修改部署目标( deployment target)

要修改部署目标,可以这样操作:在工程导航面板中,选中 iOSDiner 工程,然后选中顶部的iOSDiner(在Project下面). 接着选择 Info 选项卡,然后将 iOS Deployment Target 修改至6.0 (最新).

注意,你也可以直接在Targets列表中修改iOSDiner 生成的target,如下所示:

上面两种方法的区别是target中设置的值会替代project中设置的。如果你要生成多个target以部署到不同的平台版本上,这个方法非常有用。

使程序向后兼容

如果你希望让程序向后兼容,以支持更早的iOS版本,那么你将必须做更多的工作。如果你使用的是Storyboard(跟IOSDiner一样),那么最简单的方法就是创建2个不同的Storyboard,一个是使用Auto Layout,另外一个不使用。然后在程序启动的时候,告诉程序使用哪个Storyboard。

现在程序被设置为启动的时候自动加载一个storyboard。这涉及到工程的Main Storyboard.

要根据具体的iOS版本使用不同的storyboard,那么就不能在程序启动的时候自动加载一个storyboard了。要停止自动加载storyboard,可以这样操作:清除target中Summary 设置选项里面的 Main Storyboard 内容. 只需要清除当前的值就可以,如下图所示:

接着,选中 MainStoryboard.storyboard 然后选择 File\Duplicate…. 将新的文件命名为MainStoryboard-legacy.storyboard 并将其保存.

现在选中 MainStoryboard-legacy.storyboard, 将显示出来的编辑器设置为更小的外观尺寸,然后取消勾选 Use Autolayout.

现在打开 IODAppDelegate.m 文件,然后按照如下进行修改(来自 this 文章)

将下面的代码添加到 @implementation IODAppDelegate上面:

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)

上面的代码定义了一个宏,当你在调用这个宏的时候,可以根据用当前设备中iOS版本跟指定的版本进行比较,以判断当前的设备版本是否比制定的版本还要新。

用下面的代码替换application:didFinishLaunchingWithOptions: :

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // 1
  UIStoryboard *mainStoryboard = nil;
  if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
    mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
  } else {
    mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard-legacy" bundle:nil];
  }
 
  // 2
  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  self.window.rootViewController = [mainStoryboard instantiateInitialViewController];
  [self.window makeKeyAndVisible];
 
  return YES;
}

上面的代码会发生如下情况:

  1. 检查设备中运行的iOS版本。如果是最新的6.0,则加载开启了Auto Layout功能的storyboard。否则,加载没有开启Auto Layout功能的storyboard。
  2. 然后把storyboard创建的view controller设置给程序的window。

现在,你针对Auto Layout处理和设备的兼容,你已经有两个很好的选择了 – 但是现在还有一个大问题。

如何利用程序中额外多出来的空间呢?

有了新的界面空间,屏幕将不在像之前那样拥挤了。 针对多出来的空间最好在美学上加强设计,而不是利用多出来的空间增加功能,如果你愿意的话,本文到现在已经完成了4英寸屏幕的匹配工作,你可以停止下来了。不过增加出来的空间你可以做什么呢?

如何使用新增的空间呢?一般来说你有两个选择:

首先,如果你的程序是数据驱动型(data-driven),你可以扩大视图,以显示更多的数据。在使用list或grid时,这非常游泳,比如Twitter程序。每屏中你可以添加另外的1到2个列表项。

另外一个选择就是利用额外的空间为程序增加功能。再看看Twitter程序,你可以在底部增加一个tab bar,通过这个tab bar可以访问一些经常需要访问或者难以访问到的功能。

现在,这里有一个很好的例子 djay for iPhone.:这个例子在额外的空间中增加了功能。

在老的3.5英寸用户界面上,开发者只能在屏幕中放置两个唱盘。用户要想访问类似查看BMP或者修改拍子速度(tempo)时,必须要修改程序的界面。

而针对新的iPhone 5,可以对程序显示的内容进行优化,一些基本的BMP信息和一个拍子速度可以全部放在一个视图中。

类似上面这样增强用户界面功能是很棒的,但是这样会引入一个非常棘手的问题:如何设计或者升级一个已有的程序,以适配老的3.5英寸和新的4英寸屏幕呢?

部分答案是取决于你的程序使用的是Storyboard还是.xib文件。如果都不是,而是使用代码创建UI,那么你可能需要使用类似之前IS_IPHONE5 这样的宏来获得屏幕的尺寸,然后对UI元素做出相应的调整。

如果你使用的是Storyboard,那么让程序向后兼容是非常容易的事情 — 创建多个Storyboard,然后在代码中使用像IS_IPHONE5这样的宏来判断当前设备需要加载哪个Storyboard。

何去何从?

恭喜! 你已经成功的将一个已经存在的程序升级到适配新的iPhone 5屏幕了,并对一些界面进行了调整,以利用上额外的空间,并为程序做了向后兼容处理,以适配早期的屏幕尺寸和iOS版本。如果现在之前的大屏幕吓到你了,那么现在你应该感觉良好啦!

你可以在这里下载到完整的工程: here.

如果你希望做一些额外的练习,那么看看下面这些:

  • 利用Auto Layout将iOS Diner中的选中项窗口和箭头居中显示在屏幕中。
  • 在iOS Diner storyboard中增加一些额外的数据(4英寸屏幕可用时) — 例如,给当前食物添加一个描述。
  • 从本网站下载其它已经完成的教程工程,并把它们升级一下,以利用4英寸的屏幕 — 或者你自己的程序!

注意: 特别感谢James Prete修正了原来iOS Block程序中的一个bug。

感谢你关注本文,如果你有任何问题,那么可以根据下面的连接加入我们的论坛的讨论!


本文是由 iOS Tutorial 小组成员 Adam Burkepile撰写,他是一名全职的软件咨询师和iOS独立开发者。 这里可以看到他最近的程序: Pocket No Agenda, 还可以在 Twitterfollow他。



iPhoneCategory:

Tags: 

发表评论(Leave a Comment)

很想听听你的想法(I'd love to hear your thoughts)!

本文翻译完毕!2013-03-19 破船 :]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值