最近在掘金上分享了一篇关于性能优化文章iOS性能优化系列篇之“优化总体原则”,第一次发表文章在网上,结果收到了好多人的正面的反馈,受到了一点点鼓舞,这篇文章是很久以前组内做的一个分享,整理成文字分享给大家,里面主要内的是一些关于iOS布局常用的技术和多分辨率适配的一些方案,还略微延伸到其他平台的多分辨率适配方案,内容大多是一些资料的整理和综述,希望大家能够喜欢。
iOS平台常用布局技术
Frame
-
定义:计算绝对坐标,赋值给UIView的frame属性。
-
优点:使用简单直接,无学习成本。
-
缺点:不够灵活,在多分辨率适配或者横竖屏变化时,UIView很难根据要求自动改变布局,如果要写出adaptive的界面,需要根据不同屏幕方向、分辨率、机型等信息,相应的写很多frame变化的代码。
-
第三方库:设置frame的一些方便的第三方库, 在一定程度上解决了这些问题。比如
1.Facade链接
2.ios-view-frame-builder链接
3.Neon链接, swift版
上诉第三方库简化了手写frame的流程,并提供了比如相对位置的便捷写法还有对于view group的布局方法。但是提供给没有适配屏幕的功能。
-
个人建议:
一、 子view的布局相关的代码写在layoutSubview里面。我认为这样的好处有:
1.布局代码位置统一,其他人接手新代码的时候直接在layoutSubview就可以找到布局信息。如果把布局都写到initWithFrame中,一个问题是如果子view依赖父view的bounds,这个时候往往父view还没有得到正确的frame,比如即使你设置了UITableViewCell的高度为80,但此时你取到的还是默认的44。还一个问题是如果代码里有其他影响布局的逻辑,比如点击一个button,另外一个view变小,这样布局代码散就会落在不同的位置,带来Shotgun代码,如果把布局代码统一放到layoutSubview里面,在点击button的时候修改下状态量,再setNeedsLayout就可在layoutSubview根据状态不同采用不同的布局。
2.布局自动调用,可以实现简单的自动适配等效果。比如横竖屏的布局差异不是特别大,同一套frame布局可以实现适配,转屏的时候自动就可以重新layout,无需自己在转屏时机手动重新布局。
二、布局不要使用绝对坐标。最好结合使用屏幕宽高、相对位置(比如A的左边距离B的右边10,A的center X与父View的center X相同等)、百分比(比如A的宽度和父View的宽度相同或者是其一半)、Edge Insets(比如A的right为10)等,这样在适配要求不高的情况下也可以实现较好的适配效果。
Springs&Struts(autoresizingMask)
-
定义:Springs&Struts决定了当UIView的父View的bounds变化时,其自身的坐标如何变化:是有flexible or fixed margins (the struts), width and height (the springs)。UIView的autoresizingMask属性有如下枚举值:UIViewAutoresizingFlexibleLeftMargin、UIViewAutoresizingFlexibleWidth、UIViewAutoresizingFlexibleRightMargin、UIViewAutoresizingFlexibleTopMargin、UIViewAutoresizingFlexibleHeight和UIViewAutoresizingFlexibleBottomMargin(这些值可以取或进行合并)。
-
优点:简单,也即是使用简单方便。比如常用如果想使子view的size和父view的size始终相同,可以用UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight即可。
-
缺点:缺点也是简单,这个简单是其应用场景的简单,仅仅能使用中一些简单的布局case,从定义上就可以看出Springs&Struts描述的是子view和父view的关系,无法实现子view之间有布局相关性的复杂场景。并且没有涉及子view变化的时候具体应该变化多少。
比如想使用Springs&Struts实现如下视图的布局,示例来源链接。所有的间距是20, 上面两个view的宽度相同,所有view的高度相同:
那么如果使用Springs&Struts:
1.上方绿色view设置如下:
2.上方黄色view设置如下:
3.下面蓝色view设置如下:
经过上述对Springs&Struts的设置,转屏后,效果仍然错误,效果如下:
如果想正确实现要求的布局,只能在转屏的时候自己手动修改frame才能实现。
Autolayout
- 定义:Autolayout布局的过程本质是解决描述各个view布局信息的一组线性方程组的过程。每一个约束代表一个线性方程,用Autolayout布局的最终目的就是声明一组描述各个view布局信息的线性方程组,使得这个方程组有且有唯一解,这个解就是每个view的frame值。约束的描述:item1.attribute1 = multiplier × item2.attribute2 + constant。下图较直观的展现了什么是constraint。图片来源
-
优点:
1.Designing by intent。 Autolayout最大的优点就是摆脱以前手写frame的烦恼,用constraints来描述view本身或者view和view之间的布局关系。这是完全不同的思维也即是Designing by intent。一旦constraints建立好,剩下的都由Autolayout来替我们解决。
2.国际化。同一个表述在不同国家的语言中,文字的长度差异很大,使用Autolayout可以很好的解决这个问题。
3.多分辨率适配,无论分辨率、机型、横竖屏怎么变化,Autolayout都会替我们自动将view的frame最终设置好。
5.Dynamic Type。有关Dynamic Type的相关知识可以参考Supporting Dynamic Type。
-
缺点:
1.相对复杂,学习曲线较大,坑比较多。如果使用过Autolayout,会发现其中有很多坑,比如UIScrollView约束设置链接,忘记设置translatesAutoresizingMaskIntoConstraints为NO, Autolayout的debug调试链接,做动画等等。(其实这些也并不算什么缺点,只不过需要时间去学习和理解)。
2.大多数老工程都是基于传统的frame来进行布局,都有自己的一套布局方案,很难迁移到新技术。
3.在view多的时候或者对性能要求比较高的场合下性能会出现问题。这才是autolayout在应用到实践过程中最大的问题。这两篇文章定量的评测了autolayout在不同数量view下的性能表现Auto Layout Performance on iOS 和Optimising Autolayout 。而在实际应用过程中,的确也会有性能问题。搜狗iOS输入法在最初适配不同键盘尺寸的按键布局时,使用了 Autolayout 的解决方案,影响了键盘调起速度,后续针对键盘调起速度的优化过程中,通过Instruments的Time Profiler才定位到该问题,参考搜狗输入法性能优化实践。还有XING app的开发者在他们在项目初期,在列表的布局上使用了Autolayout。带来了无法解决的性能问题,所以放弃使用Autolayout,博客链接Auto Layout in Cells – Don’t!。还有LinkedIn团队也遇到了同样的问题,他们为此开发了LayoutKit来代替Autolayout,他们在介绍LayoutKit的时候,这样写道"LinkedIn created LayoutKit because we have found that Auto Layout is not performant enough for complicated view hierarchies in scrollable views."
-
使用Autolayout常用的几种方式:
1.直接使用 NSLayoutConstraint的constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:方法。例如:
2.使用NSLayoutAnchor。例如:
NSLayoutAnchor在iOS9之后才能使用,苹果推出NSLayoutAnchor的原因我猜测应该是参考了市面上流行的第三方库的解决办法,为了解决使用1方法创建constraint过于繁琐的问题。UIView具体属性有:3.Visual Format Language(VFL)。例如:
VFL应用起来比较简洁方便,不过由于创建的constraints无法单独去操作,所以调试起来很不方便,很难做动画。4.使用interface builder, 从Apple对interface builder的不断改进还有WWDC中相关视频等信息中,我们可以发现Apple认为使用interface builder创建constraints才是best practice。这就把话题引到了一直存在的很大争议,到底是用纯手工写布局好还是使用使用interface builder好。这里有喵神写的博客代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧和唐巧的文章iOS 开发中的争议(二)。具体如何选择大家可自己判断。
5.其他第三方库。因为大家对苹果提供的Autolayout的API不满意,Github上有很多针对对Autolayout封装的库,使用起来大大减少了代码量,很好上手。比如其中Objc写的、最为广泛使用的Masonry和PureLayout,swift语言写的SnapKit和Cartography。有兴趣的可自己了解下。
6.Stack Views. UIStackView(iOS9+)class provides a streamlined interface for laying out a collection of views in either a column or a row. Stack views let you leverage the power of Auto Layout, creating user interfaces that can dynamically adapt to the device’s orientation, screen size, and any changes in the available space. The stack view manages the layout of all the views in its arrangedSubviews property. These views are arranged along the stack view’s axis, based on their order in the arrangedSubviews array. The exact layout varies depending on the stack view’s axis, distribution, alignment, spacing, and other properties. 其实Stack View和Android的Linear Layout类似,都是提供在同一方向(横向或者纵向)布局多个view的便捷方法。我觉得iOS中不仅仅是UIStackView,UICollectionView使用得当,在特定的应用场景下也可以简单地实现适配不同屏幕的作用。
-
学习Autolayout。可以参考Apple的GuideAuto Layout Guide。还有一些优秀的博文,比如objc上的Advanced Auto Layout Toolbox还有raywenderlich上的Auto Layout Tutorial in iOS 9 Part 1: Getting Started和Auto Layout Tutorial in iOS 9 Part 2: Constraints还有WWDC上关于Autolayout相关的视频等等。
第三方布局方案
除了上面苹果官方提供的两种布局技术,还有其他的方案,比如:
-
CSSLayout,是Facebook开源的对flexbox跨平台的实现。他主要的目的是使web, android, iOS, 和windows的开发者使用同一种布局技术来实现布局,节省学习成本,尤其是对web开发者。
-
ComponentKit,也是是Facebook开源的项目。官方介绍目前Facebook的iOS app大多都使用componentkit。 componentkit使用functional, declarative的方式去构建UI。官方介绍其优点有:
1."ComponentKit takes a functional, declarative approach to building UI and emphasizes a one-way data flow from immutable models to immutable components that describe how views should be configured" "It was built to power Facebook's News Feed and is now used throughout the Facebook iOS app."
2."It performs layout on a background thread, creates the minimal view hierarchy to render the components on screen and has intelligent view reuse. This results in great scroll performance and a snappy system overall."
-
LayoutKit 官方介绍"LinkedIn created LayoutKit because we have found that Auto Layout is not performant enough for complicated view hierarchies in scrollable views."并且和autolayout做了对比:
LayoutKit has many benefits over using Auto Layout:
1.Fast: LayoutKit is as fast as manual layout code and significantly faster than Auto Layout.
2.Asynchronous: Layouts can be computed in a background thread so user interactions are not interrupted.
3.Declarative: Layouts are declared with immutable data structures. This makes layout code easier to develop, code review, debug, and maintain.
4.Cacheable: Layout results are immutable data structures so they can be precomputed in the background and cached to increase user perceived performance.
-
MyLayout, 这个是国内的iOS开发者写的,其个人在主页上介绍项目的亮点在于“一套功能强大的iOS界面布局库,他不是在AutoLayout的基础上进行的封装,而是一套基于对frame属性的设置,并通过重载layoutSubview函数来实现对子视图进行布局的布局框架。因此可以无限制的运行在任何版本的iOS系统中。其设计思想以及原理则参考了Android的布局体系和iOS自动布局以及SizeClass的功能,通过提供的:线性布局MyLinearLayout、相对布局MyRelativeLayout、框架布局MyFrameLayout、表格布局MyTableLayout、流式布局MyFlowLayout、浮动布局MyFloatLayout、路径布局MyPathLayout七个布局类,以及对SizeClass的支持,来完成对界面的布局。MyLayout具有功能强大、简单易用、几乎不用设置任何约束、可以完美适配各种尺寸的屏幕等优势。”
上面介绍了一些第三方的布局方案,大家有兴趣可以研究下,特别是ComponentKit。不过在实际应用的过程中对这些第三方库需要谨慎使用,需要彻底理解其原理并针对项目特点进行调研,要在使用成本和带来的收益之间进行平衡。
其他平台常用布局技术
由于早期iOS平台上屏幕分辨率种类较少,即使到后期和Android或者web相比也是不多,再加上目前市面上的app大多仅支持iPhone且为竖屏,导致开发者对多分辨率适配并不重视。相关适配的文章也不多。在适配方面我们可以借鉴下其他平台的解决方案,开阔下自己的思路。由于我没有做深入的学习,仅做简单介绍,有兴趣的同学可以自行深入了解。
Android平台布局技术
和iOS类似,Android声明布局也大体有两种途径:参考
1.Declare UI elements in XML.(在iOS平台,Xcode以XML格式储存xib和storyboard文件内容。编译时,Xcode将xib和storyboard文件编译成二进制文件,即nib文件。运行时,nib文件会被载入并实例化来创建新的视图。)
2.Instantiate layout elements at runtime.
具体的布局的手段有参考:
- Relative Layout is a view group that displays child views in relative positions. The position of each view can be specified as relative to sibling elements (such as to the left-of or below another view) or in positions relative to the parent RelativeLayout area (such as aligned to the bottom, left or center).
- Linear Layout(和iOS中的UIStackView类似)LinearLayout is a view group that aligns all children in a single direction, vertically or horizontally. You can specify the layout direction with the android:orientation attribute.
- Building Layouts with an Adapter, 比如List View(UITableView)和Grid View(UICollectionView)
- Constraint Layout(Autolayout) ConstraintLayout allows you to create large and complex layouts with a flat view hierarchy (no nested view groups). It's similar to RelativeLayout in that all views are layed out according to relationships between sibling views and the parent layout, but it's more flexible than RelativeLayout and easier to use with Android Studio's Layout Editor.
其他平台多分辨适配策略
Android平台多分辨适配策略
参考1 参考2 参考3
Android和iOS是目前市场份额最大的两个移动平台,由于Android平台的开放性,导致其碎片化极为严重,当然随之而来的屏幕的尺寸也十分繁杂(如图),因此多分辨率的适配工作对于Android平台来说应该是一个极为重要的事情。作为iOS开发者,我们可以了解下Android平台的适配策略,看是否有可以借鉴的地方。
从上图可以看出,Android平台的屏幕的种类是多么的繁杂。The foundation of Android's support for multiple screens is its ability to manage the rendering of an application's layout and bitmap drawables in an appropriate way for the current screen configuration. The system handles most of the work to render your application properly on each screen configuration by scaling layouts to fit the screen size/density and scaling bitmap drawables for the screen density, as appropriate. To more gracefully handle different screen configurations, however, you should also:
- Explicitly declare in the manifest which screen sizes your application supports
- Provide different bitmap drawables for different screen densities
- Using configuration qualifiers(Size、Density、Orientation和Aspect ratio等)
- Designing alternative layouts and drawables
Best Practices
- Use wrap_content, match_parent, or the dp(iOS中的point类似,) unit for layout dimensions. If you use "wrap_content"(iOS中的Intrinsic Content Size类似), the width or height of the view is set to the minimum size necessary to fit the content within that view, while "match_parent" makes the component expand to match the size of its parent view.
- Use RelativeLayout. Do not use hard-coded pixel values in your application code.Do not use AbsoluteLayout
- Use Size Qualifiers. Your application should also provide several alternative layouts to target different screen configurations. You do so by using configuration qualifiers, which allows the runtime to automatically select the appropriate resource based on the current device’s configuration (such as a different layout design for different screen sizes).
- Use the Smallest-width Qualifier. The Smallest-width qualifier allows you to target screens that have a certain minimum width given in dp.
- Use Orientation Qualifiers.
- Use Layout Aliases 为了兼容性和减少重复布局,Layout Aliases可以是多个限定符描述对应同一个layout.xml
- Use Nine-patch Bitmaps(.9.png), 和iOS中的resizable image类似,Xcode中的Image Slicing也可以帮助开发者用可视化的方式完成resizable image
- Build a Responsive UI with ConstraintLayout参考
从上面介绍的官方适配参考来看,Android平台适配的总体思路就是将设备按照屏幕的特点分成不同的类别,同类别的屏幕具有差别不大的适配特性,然后通过Qualifier来为不同的屏幕分类提供不同的资源(layout,image等)。总体思路和iOS平台有些相似也有不同,比如Android平台使用的Qualifiers,iOS平台也会根据不同屏幕给出2X 3X、设备类型(iPhone iPad)、size class、memory等属性对应的图片,只不过Android平台的Qualifiers更丰富,对设备区分的更详细。还有xml的使用上,我个人觉得Android平台的更轻量级一些(虽然Android也有和iOS类似的interface builder), Android平台对xml的定位个人感觉更像CSS。我觉得这个是我们做iOS开发可以借鉴的一个地方,用比较轻量级的配置文件(xml、json或plist)来将客户端布局的部分和业务逻辑分离开,增加其扩展性。由于interface builder无法动态下发,而使用xml不仅可以完成由数据驱动UI,还可以动态下发布局,特别适合需要支持不同主题,或者有着比较强烈的界面动态化需求的应用。
iOS平台多分辨率适配策略及实例
之前介绍了iOS平台常用布局技术,这些都是布局的工具,单一的布局技术并不能解决多分辨率适配的问题,要适配多分辨率需要将多种相关布局技术结合起来并需要采用一定的适配策略。下面是常用的适配策略:
- Adaptive User Interfaces下面Apple官方推荐的多分辨率适配的解决方案,可以参考官方的GuideAdaptive User Interfaces,还有一些优秀的博文,比如iOS 中的 UI 自适应、WWDC 2014 Session笔记 - iOS界面开发的大一统。这里我简单的整理和介绍下,大家可以有空可以仔细的学习下,毕竟这是官方推荐,代表以后的发展趋势。
Best Practice
1.Interface Builder. Apple一直不遗余力的推广和改进Interface Builder,Interface Builder可很方便的设置constraints,特别从iOS8的Size Class概念的提出,Interface Builder在Adaptive User Interfaces的优势更加明显。具体可以参考Adaptive Layout Tutorial in iOS 9: Getting Started
2.Image Asset。使用Image Asset可为不同的设备提供不同的图片素材,以达到最优的用户体验。下图展示了目前Image Asset可以配置的选项。配置好后在对应的目录下其实是一个json配置文件(我们也可以参考这个方案,自己写配置文件,来支持更复杂的图片配置逻辑),编译后生成.car文件。
其中有几个选项大家可以关注下,一个是Width还有Height。这个就是可以指定Size Class的选项。还有Scale Factors,这个选项有Single Vector或Vector With Overrides(Vector With Overrides是Single Vector的增强, 可以在放置完矢量图之后继续放置@1x、@2x和@3x的png格式的图片。放置的png会优先覆盖矢量图, 未放置对应倍率图片的设备才会使用矢量图对应生成的图片),这个选项主要是为了支持矢量图,可以只放一张PDF的图片,编译后Xcode会自动生成1x,2x,3x的图,需要注意的是使用他并不会减少包的体积,因为不是运行时的特性。还有Slicing,可以在图形化界面里设置拉伸参数。虽然Image Asset有诸如使用方便等优点,但是我们在使用过程中还是需要衡量其带来的便捷性和问题。(1)比如Image Asset会生成1X图片,目前很多应用已经不支持1X的设备了,这样会带来包大小的问题。(2)Image Asset虽然支持矢量图,但是并不是运行时的特性,编译后仍然会生成1x 2x 3x图片,对安装包大小没有起到减少的作用,甚至会更大(一个是多了1x图片,另外一个是如果自己提供2x 3x图片可在添加前用一些工具用png图片压缩),在图片对安装包大小影响的优化上,一个优化点是可以自己实现对矢量图的支持,这样就提供一份PDF即可,另一个是使用工具对png图片压缩,还一个比较极端优化的方式是自己在代码里面画图片(可以第一次画然后本地化,之后就直接读取磁盘文件),在具体实施的过程中,可以借用PaintCode来节省自己编写绘图代码的时间。 (3)还有其Image Asset只支持imageNamed,这样如果一些应用想有自己的图片缓存策略的话就无法实现了。
3.UITraitCollection。 Apple的API文档里面这样介绍UITraitCollection: A trait collection describes the iOS interface environment for your app, including traits such as horizontal and vertical size class, display scale, and user interface idiom. To create an adaptive interface, write code to adjust your app’s layout according to changes in these traits. The iOS trait environment is exposed though the traitCollection property of the UITraitEnvironment protocol. This protocol is adopted by the following classes: UIScreen, UIWindow, UIViewController, UIPresentationController, and UIView. You access specific trait values using the UITraitCollection horizontalSizeClass, verticalSizeClass, displayScale, and userInterfaceIdiom properties. The values that express idiom and size traits are defined in the UIUserInterfaceIdiom and UIUserInterfaceSizeClass enumerations; the value for the display scale trait is expressed as a floating point number. To make your view controllers and views responsive to changes in the iOS interface environment, override the traitCollectionDidChange: method from the trait environment protocol. To customize view controller animations in response to interface environment changes, override the willTransitionToTraitCollection:withTransitionCoordinator: method of the UIContentContainer protocol.
UITraitCollection图例:
UITraitCollection变化流程:
上图是在代码里面根据UITraitCollection的变化相应的改变布局。如果用Interface Builder的话,系统会帮你自动处理UITraitCollection变化所需要调整的部分。Size Classes。是UITraitCollection里面和Adaptive User Interfaces关系比较大的属性。Size Classes是iOS8之后苹果最新提出来的,和以往的将屏幕以具体尺寸划分不同,Size Classes对屏幕进行了抽象分类,通过屏幕的感官表现,将其分为普通 (Regular) 和紧密 (Compact) 两个种类 (class)。这样就把屏幕的适配工作从无穷尽的尺寸适配转换成3*3种屏幕的适配,我们可以在同一种类的屏幕上使用同一种布局,大大减少了适配工作量。以前universal应用使用storyboard时,分成iPad.storyboard 和iPhone.storyboard 来分别写,使用了Size Classes就不需要这么麻烦了。 特别在iOS9中,随着多任务 (multi-tasking) 的推出,这个概念变得愈发重要。
4.Dynamic Type 可以根据Trait Collection的变化调整字体。
5.Layout Guides 参考 The UILayoutGuide class defines a rectangular area that can interact with Auto Layout. Use layout guides to replace the dummy views you may have created to represent inter-view spaces or encapsulation in your user interface. Traditionally, there were a number of Auto Layout techniques that required dummy views. A dummy view is an empty view that does not have any visual elements of its own and serves only to define a rectangular region in the view hierarchy. For example, if you wanted to use constraints to define the size or location of an empty space between views, you needed to use a dummy view to represent that space. If you wanted to center a group of objects, you needed a dummy view to contain those objects. Similarly, dummy views could be used to contain and encapsulate part of your user interface. Dummy views let you break up a large, complex user interface into self-contained, modular chunks. When used properly, they could greatly simplify your Auto Layout constraint logic.
There are a number of costs associated with adding dummy views to your view hierarchy. First, there is the cost of creating and maintaining the view itself. Second, the dummy view is a full member of the view hierarchy, which means that it adds overhead to every task the hierarchy performs. Worst of all, the invisible dummy view can intercept messages that are intended for other views, causing problems that are very difficult to find.
The UILayoutGuide class is designed to perform all the tasks previously performed by dummy views, but to do it in a safer, more efficient manner. Layout guides do not define a new view. They do not participate in the view hierarchy. Instead, they simply define a rectangular region in their owning view’s coordinate system that can interact with Auto Layout.
Layout guides can be used to define an equal spacing between a series of views.
Layout guides can also act as a black box, containing a number of other views and controls. This lets you encapsulate part of your view, breaking your layout into modular chunks.
6.UIAppearance 可以通过appearanceForTraitCollection获取特定UITraitCollection的UIAppearance,然后对UIAppearance进行自定义适配,以达到不同UITraitCollection自动使用不同的UIAppearance。
-
Web View。这块其实并不是Native的解决方案,其适配的所需要的技术和策略在web的端早就有很多比较成熟的方案。但是在客户端开发中有一定的应用场景,比如一些运营需求较高的场合,需要做到很强的布局和逻辑的动态化(当然这种情况也可以使用Reactive Native、 Weex、luaView甚至JS Patch等动态化方案)。另外一种情况是展示类网页内容的app,比如腾讯新闻、天天快报和今日头条等。这些app展示的内容的排版大多从网页而来,如果采用native的方式来解决会十分复杂,因此在大多情况下都使用web view。
-
代码里判断机型、屏幕尺寸、横竖屏等状态,根据不同状态并结合一定的缩放策略给UIView设置不同的frame。这种方式属于比较简单的适配方案,如果项目页面比较多,view的层次比较复杂的话,需要适配的分辨率种类多,代码里会有很多判断的代码,最致命的是如果新增屏幕尺寸需要适配的话,需要很大的工作量。虽然这种方式缺点很多,但也是目前确实国内各大小app使用最多的方案。主要原因有:
1.项目立项早。早期iOS布局技术较为单一,且屏幕尺寸也很少。所以大部分都是采用手写frame。随着新的屏幕尺寸的增加,由于迁移到新的技术成本太大,所以大多简单适配了事。
2.所需适配分辨率不多。目前大多数应用都是仅支持iPhone版,且除了少数页面大多数页面都是竖屏。所以需要适配的分辨率就有限了。除了320 × 480之外,其他三种屏幕的高宽比基本都在1.78附近。所以一般设计只需要给出一种分辨率的设计稿(一般选择iPhone6--“为什么选择iPhone 6作为基准尺寸”或者iPhone5), 只要写frame注意前面讲的一些事项之外,再配合一些简单的缩放策略即可实现适配工作,这是知乎上手机淘宝团队回答的适配和缩放策略。手淘适配规则总结起来就一句话:文字流式,控件弹性,图片等比缩放。控件弹性指的是,navigation、cell、bar 等适配过程中垂直方向上高度不变;水平方向宽度变化时,通过调整元素间距或元素右对齐的方式实现自适应。这样屏幕越大,在垂直方向上可以显示更多内容,发挥大屏幕的优势。
- 使用配置文件驱动UI布局。这部分其实是参考Android的适配方案,可以为不同屏幕尺寸设计一套或者多套的layout,其中配置文件中可以加入一些缩放策略。然后根据屏幕不同采用不同的配置文件。这种方式的好处是将布局和业务逻辑分开、适配扩展性好、可以动态下发配置文件改变UI布局。