iOS多解析度適配綜述

Hello_Vincent發表於2018-04-08

最近在掘金上分享了一篇關於效能優化文章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的高度相同:

iOS多解析度適配綜述

那麼如果使用Springs&Struts:

1.上方綠色view設定如下:

iOS多解析度適配綜述

2.上方黃色view設定如下:

iOS多解析度適配綜述

3.下面藍色view設定如下:

iOS多解析度適配綜述

經過上述對Springs&Struts的設定,轉屏後,效果仍然錯誤,效果如下:

iOS多解析度適配綜述

如果想正確實現要求的佈局,只能在轉屏的時候自己手動修改frame才能實現。

Autolayout

  • 定義:Autolayout佈局的過程本質是解決描述各個view佈局資訊的一組線性方程組的過程。每一個約束代表一個線性方程,用Autolayout佈局的最終目的就是宣告一組描述各個view佈局資訊的線性方程組,使得這個方程組有且有唯一解,這個解就是每個view的frame值。約束的描述:item1.attribute1 = multiplier × item2.attribute2 + constant。下圖較直觀的展現了什麼是constraint。圖片來源

iOS多解析度適配綜述

  • 優點:

    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 iOSOptimising 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:方法。例如:

    iOS多解析度適配綜述

    2.使用NSLayoutAnchor。例如:

    iOS多解析度適配綜述
    NSLayoutAnchor在iOS9之後才能使用,蘋果推出NSLayoutAnchor的原因我猜測應該是參考了市面上流行的第三方庫的解決辦法,為了解決使用1方法建立constraint過於繁瑣的問題。UIView具體屬性有:
    iOS多解析度適配綜述

    3.Visual Format Language(VFL)。例如:

    iOS多解析度適配綜述
    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寫的、最為廣泛使用的MasonryPureLayout,swift語言寫的SnapKitCartography。有興趣的可自己瞭解下。

    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 StartedAuto 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).
    iOS多解析度適配綜述
    iOS多解析度適配綜述
  • 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.
    iOS多解析度適配綜述
    iOS多解析度適配綜述
  • 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平臺的適配策略,看是否有可以借鑑的地方。

iOS多解析度適配綜述
從上圖可以看出,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平臺常用佈局技術,這些都是佈局的工具,單一的佈局技術並不能解決多解析度適配的問題,要適配多解析度需要將多種相關佈局技術結合起來並需要採用一定的適配策略。下面是常用的適配策略:

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檔案

iOS多解析度適配綜述

其中有幾個選項大家可以關注下,一個是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圖例:

iOS多解析度適配綜述

UITraitCollection變化流程:

iOS多解析度適配綜述

iOS多解析度適配綜述
上圖是在程式碼裡面根據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) 的推出,這個概念變得愈發重要。

iOS多解析度適配綜述

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。

iOS多解析度適配綜述

  • 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 等適配過程中垂直方向上高度不變;水平方向寬度變化時,通過調整元素間距或元素右對齊的方式實現自適應。這樣螢幕越大,在垂直方向上可以顯示更多內容,發揮大螢幕的優勢。

iOS多解析度適配綜述

  • 使用配置檔案驅動UI佈局。這部分其實是參考Android的適配方案,可以為不同螢幕尺寸設計一套或者多套的layout,其中配置檔案中可以加入一些縮放策略。然後根據螢幕不同採用不同的配置檔案。這種方式的好處是將佈局和業務邏輯分開、適配擴充套件性好、可以動態下發配置檔案改變UI佈局。

相關文章