iOS編程實戰 — 新的UI範式

iOS 7給蘋果設備帶來了全新的用戶界面(UI)。iOS 7在UI上的變化是自其誕生以來最大的。iOS 7專一於三個重要的特色:清晰、依從和層次。理解這三個特色很重要,由於這有助於設計跟原生的系統內置應用同樣的應用。面試

本章將介紹iOS 7引入的一些重要變化以及如何讓應用使用這些新特性。前半章展現開發者應該瞭解的重要的UI範式,利用這些範式可使應用更上一層樓。後半章展現如何把已有的iOS 6應用遷移到iOS 7上,而且須要的話,也能夠保持向後兼容性。安全

2.1 清晰、依從和層次

清晰(clarity)很簡單,就是對用戶來講表達的意思是清晰的。大部分iOS用戶會抓住一些碎片時間使用應用,他們會打開Facebook,查看通知或者新聞訂閱,發佈狀態更新或照片,而後關閉應用。至少在iPhone上,不多有應用是用戶長時間使用的。事實上統計代表,對於大部分應用,用戶每次只會用80秒左右。這意味着開發者必須在極短的時間內把信息傳遞給用戶,所以應該把最重要的信息清晰地展現在屏幕上。舉個例子,若是開發天氣應用,溫度和天氣情況是用戶最感興趣的兩塊信息,要把UI設計得足夠簡潔,讓用戶不須要在視野範圍內尋找就能直接看到。app

依從(deference)是說操做系統不會提供和應用的UI競爭的UI,相反,它依從於應用及其內容。這意味着每一個應用都會有獨一無二的外觀和體驗。在iOS 7以前,應用的UI是用戶看到的在系統提供的導航欄和工具欄內部的東西,鍍層效果、不規則邊框和漸變色被依從於其背後內容的半透明欄取代。操做系統的默認應用依從於內容,而UI在大部分狀況下只起輔助做用。編輯器

爲iOS 7設計的應用應該具備層次(depth)的概念。控件和內容應該處於不一樣的層,從home screen開始就是這樣,視差效果給人感受圖標是浮在最上面的一層上,模態化的警告框也有相似效果。通知中心和控制中心也有層次,它們用的是模糊和半透明而不是視差效果。ide

2.2 動畫、動畫、動畫

使用iOS 7後開發者發現的第一件事可能就是應用的視覺擬真(擬物)沒有了。陰影很不明顯,幾乎看不出來,拋光按鈕徹底消失了。真實世界的擬物元素,好比備忘錄(iPhone)和通信錄(iPad)的人造革,也都不見了。函數

最重要的是,應用程序窗口默認就是全屏的,狀態欄如今是半透明的,浮在應用程序窗口的上方。注意,直到iOS 6,應用程序的全屏和狀態欄的半透明一直都只是可選的。在iOS 6中,必須把導航欄的translucent屬性設置爲YES,而且把視圖控制器的wantsFullScreenLayout設置爲YES才行。在iOS 7中全部的窗口默認都是這麼設置的。工具

一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個個人iOS交流羣:1012951431, 分享BAT,阿里面試題、面試經驗,討論技術, 你們一塊兒交流學習成長!但願幫助開發者少走彎路。佈局

儘管視覺擬真沒有了,iOS 7強化了運動擬真。運動擬真的強化從鎖屏開始。試着拖動攝像頭按鈕把鎖屏界面「提起來」,而後從屏幕中間「掉下來」,你會看到鎖屏界面會在碰到屏幕底部時彈起來。如今再試着把鎖屏界面往屏幕底部推一下來「撞擊」,你會看到彈得更厲害了,就跟真實世界的物體撞到表面同樣。因此,擬物並無徹底從iOS 7中消失,以前版本的iOS強調視覺擬物,而iOS 7更加劇視物理擬物。學習


iOS 7仍然是擬物的,只不過不是強調視覺擬物而是物理擬物,屏幕上的物體聽從物理定律,其行爲相似於真實世界的物體。字體


2.2.1 UIKit Dynamics

在應用中實現物理特性很簡單,iOS 7引入了一個新類UIDynamicAnimator,用來模擬真實世界的物理定律。開發者能夠建立一個UIDynamicAnimator對象並將其添加到視圖上,這個視圖一般是視圖控制器的根視圖,在UIKit Dynamics上下文中一般也被稱爲引用視圖,引用視圖的子視圖如今就會基於其關聯的行爲聽從物理定律。

行爲能夠經過聲明定義並添加到視圖。事實上,任何聽從UIDynamicItem協議的對象均可以添加行爲。UIView及其子類(包括UIControl)聽從這個協議,這意味着屏幕上可見的任何東西幾乎均可以關聯一種行爲。

這裏還有一件有意思的事情,UICollectionViewLayoutAttributes聽從UIDynamicItem協議,這樣可讓集合視圖的元素有動力學行爲。默認的信息應用就是一個例子。

2.2.2 UIMotionEffect

物理擬物還沒完。主屏幕上的視差效果,警告框好像浮動在視圖上方的效果,Safari新的切換選項卡UI在傾斜設備時會顯示「更多」內容,這些都是真實行爲的模擬。用UIMotionEffect很容易就能爲應用添加這類特性。iOS 7中的一個新類UIInterpolatingMotionEffect,能讓開發者不費吹灰之力就添加這類效果。能夠把UIMotionEffect理解爲跟CAAnimation相似。CAAnimation會對其所屬的層作動畫,UIMotionEffect會對其所屬的視圖作動畫。CAAnimation的動畫是時間的函數,UIMotionEffect的動畫則是設備動做的函數。咱們會在第19章詳細介紹UIKit Dynamics和UIMotionEffect。


CAAnimation動畫是時間的函數,UIMotionEffect是設備動做的函數。


2.3 着色

UIView有了一個新屬性,叫作tintColor,能夠給應用着色。全部做爲其餘視圖的子視圖存在的UI元素都會在未設置tintColor的狀況下使用父視圖的tintColor。這意味着給應用程序的窗口設置tintColor就能夠獲得全局的着色。

這裏要注意的很重要的一點是當模態化視圖出現時,iOS 7會將其背後全部的UI元素變模糊。若是開發者有一個自定義視圖,而且用了父視圖的tintColor來作一些自定義渲染,就要覆蓋tintColorDidChange方法來更新變化。


也能夠在Xcode的故事板編輯器的File inspector面板中設置tintColor


2.4 用半透明實現層次和上下文

UIKit Dynamics和UIMotionEffect能幫助用戶理解應用中的空間深度。iOS 7中還有一個強化空間深度概念的特性是在大部分模態化窗口上統一使用了模糊和半透明效果。控制中心和通知中心用一種精細的方式模糊了背景,以便用戶能知道背後是什麼。

iOS 7經過直接讀取顯存來實現這種效果。遺憾的是,iOS 7沒有提供SDK來讓開發者輕鬆實現這種效果,多是出於安全上的考慮。好比說,沒法這麼作:

self.view.blurRadius = 50.0f;
self.view.saturationDelta = 2.0f;

 

不過,有一個WWDC講座中的示例代碼有UIImage的分類,UIImage+ImageEffects(本書的示例代碼中有)容許實現這種效果,儘管這種方法很難用也不直觀。可是你想超越極限,這也是你閱讀本書的緣由,不是嗎?因此,在本身的應用中實現這種效果吧。

如今要展現如何建立一個看起來像通知中心或者控制中心背景的圖層。首先建立一個單視圖應用,挑一張漂亮的背景圖加上,再添加一個按鈕。接下來寫一個按鈕動做處理方法,彈出一個會將後面的背景模糊的視圖。

捷徑(或者說投機取巧)是建立一個不可見的UIToolbar並使用它的圖層,而不是建立新圖層。不過這種技巧很容易失效,因此不推薦。更好的辦法是用iOS 7新的UIScreenshotting接口截屏,切割截屏圖片,爲其添加模糊效果,並把模糊的圖片做爲彈出視圖的背景。

來看看代碼:

UIImage+ImageEffects建立模糊的彈出層(SCTViewController.m)

// 建立圖層**
self.layer = [CALayer layer];
self.layer.frame = CGRectMake(80, 100, 160, 160);
[self.view.layer addSublayer:self.layer];

**// 截屏**
float scale = [UIScreen mainScreen].scale;
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, YES, scale);
[self.view drawViewHierarchyInRect:self.view.frame afterScreenUpdates:NO];
__block UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

**// 裁剪截圖**
CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage,
   CGRectMake(self.layer.frame.origin.x * scale,
              self.layer.frame.origin.y * scale,
              self.layer.frame.size.width * scale,
              self.layer.frame.size.height * scale));
image = [UIImage imageWithCGImage:imageRef];

**// 添加效果**
image = [image applyBlurWithRadius:50.0f
                         tintColor:
[UIColor colorWithRed:0 green:1 blue:0 alpha:0.1]
             saturationDeltaFactor:2
                         maskImage:nil];
// 放到新建的圖層上
self.layer.contents = (__bridge id)(image.CGImage);

 

applyBlurWithRadius:tintColor:saturationDeltaFactor:maskImage:方法位於UIImage+ImageEffects分類中,包括分類在內的完整代碼能夠從本書網站上下載。

圖2-1顯示了代碼運行的效果。

【插入P25圖】

圖2-1 應用在iOS 7中運行時彈出視圖先後的截屏

2.5 動態字體

在iOS 7中,用戶能夠設置文字大小。內置的郵件、日曆以及其餘大部分應用都會按照這個設置動態改變文字大小。注意增大文字大小並不老是能讓字體的磅數變大。當文字大小設置的值可能會讓小號字體沒法辨認時,iOS 7會自動加粗文字。爲應用增長動態字體支持後,還能夠在設置應用中動態改變文字大小。不過,iOS 7的動態字體有一個缺點:在寫做本章時,還不支持自定義字體。第21章會介紹動態字體。

2.6 自定義過渡效果

iOS 7的另外一個新特性是蘋果在大部份內置應用中儘可能減小了屏幕切換的使用。打開日曆應用,點擊一個日期,日期視圖以自定義的過渡動畫效果從月視圖中出現。相似地,建立新事件時,改變事件的開始和結束時間也是用動畫實現自定義過渡。注意,這個動畫在以前版本的iOS中是導航控制器的默認推入頁面操做動畫。還有一個例子是照片應用中的照片選項卡,萬年不變的相機膠捲被一個使用自定義過渡在年度視圖、精選視圖、時刻視圖和單張照片視圖之間切換的集合視圖替代了。iOS 7新的UI範式強調讓用戶知道本身在哪裏,而不是讓他們迷失在推入的無數視圖控制器中。大部分狀況下,這些動畫都用自定義過渡實現,如圖2-2所示。

【插入P26圖】

圖2-2 日曆應用的屏幕,顯示使用自定義過渡的屏幕

爲iOS 7設計應用時,要認真考慮使用自定義過渡是否對於讓用戶知道本身在哪兒有所幫助。iOS 7 SDK增長了接口,能毫無困難地實現這些動畫。

2.6.1 自定義過渡類型

iOS 7的SDK支持兩類自定義過渡:自定義視圖控制器過渡和交互式視圖控制器過渡。自定義視圖控制器過渡以前也能實現,要用到故事板和自定義聯線。交互式視圖控制器過渡則讓用戶利用手勢(一般是拖動)控制過渡的過程(從開始到結束)。所以當用戶拖動或快速滑動手指時,會從一個視圖控制器過渡到另外一個。

當過渡是時間的函數時,一般是自定義視圖控制器過渡,是手勢識別器的參數或相似事件的函數時,一般是交互式視圖控制器過渡。

好比,能夠認爲導航控制器的推入過渡(就像iOS 6那樣)是一種自定義視圖控制器過渡,而UIPageViewController則是交互式視圖控制器過渡。使用UIPageViewController在視圖之間翻頁時,過渡跟時間無關,頁面的過渡跟着手指的移動走,因此這是交互式視圖控制器過渡。而UINavigationController過渡(在iOS 6中)在一段時間內發生,因此這類過渡是自定義視圖控制器過渡。

iOS 7 SDK容許開發者自定義幾乎任何類型的過渡:視圖控制器的presentation和dismissal、UINavigationController的推入和彈出過渡、UITabbarController的過渡(UITabbarController默認不對視圖控制器作動畫),甚至是集合視圖的佈局變化過渡。

自定義視圖控制器過渡比交互式視圖控制器過渡更易使用。本章會展現如何建立自定義視圖控制器過渡。交互式視圖控制器過渡相對較難使用,第20章會介紹這個主題。

2.7 把應用過渡(遷移)到iOS 7

到目前爲止,本章介紹了iOS 7中引入的主要UI範式並實現了其中一種:模糊效果。在本節中,咱們會展現如何把應用從iOS 6過渡到iOS 7。

你已經知道了,iOS 7的UI和以前的版本大不相同。所以,你得了解大量的API變化。可能的話,徹底放棄對iOS 6的支持,由於iOS 7的升級率要比iOS 6高得多。不過,若是業務須要支持iOS 6,繼續閱讀下一節,咱們會展現如何在不犧牲iOS 6的狀況下支持iOS 7。

2.7.1 UIKit變化

在iOS 7中,幾乎全部的UI元素都發生了變化。按鈕沒有邊框,開關和分段控件變小了,滑塊和進度條變細了。若是使用自動佈局,大部分變化都不會對你有什麼影響。若是沒有使用自動佈局,那麼是時候把nib文件升級到自動佈局了。若是不使用自動佈局,那麼在3.5寸和4寸設備上支持iOS 6和iOS 7就須要寫大量的佈局代碼。

若是你以前一直不想使用自動佈局,那麼如今必須開始學習了。Xcode 5中的自動佈局要比Xcode 4.x中的好用得多,本書第6章會更爲詳細地講解自動佈局。

2.7.2 自定義設計

通常來講大部分應用都會用自定義設計圖來作應用皮膚,開發者須要仔細考慮如何設計。緣由是iOS 7的設計是很是「平」的,視覺擬物削弱了不少。這麼作是由於在iPhone 4以前,幾乎全部的屏幕(手機/PC/Mac)像素密度都在70 ppi~160 ppi(每英寸像素數)之間。iPhone 4的視網膜屏將像素密度增長到了320 ppi。這個像素密度接近健康人眼所能接受的最高程度,再多就是人眼接受不到的多餘數據了。這也是印刷業採用300 ppi的緣由。

印刷業不須要模擬拋光發亮的按鈕、不規則邊框、漸變或者藝術字體。你何時見過廣告牌或者雜誌封面的圖上加上人造拋光或者發亮的效果?沒有。爲何?由於不須要。(有些雜誌有光澤,但那是真的光澤。)事實上,軟件設計師利用拋光、發亮按鈕來讓他們的設計在(當時的)低分辨率(70 ppi~160 ppi)屏幕上看起來比較好看。

而iPhone 4屏幕的像素密度達到了接近高印刷質量的雜誌的程度,爲UI添加光澤和發光效果就沒有必要了。這就是Twitterrific 五、LetterPress和Clear(代辦事項應用)甚至在蘋果以前就大量減小了界面效果的緣由。Windows Phone 7界面從第一天開始就沒有拋光、發亮或者陰影。

今天,除了iPad mini,蘋果在2011年和2012年間發佈的幾乎全部iOS設備都採用了視網膜屏。扁平化設計是將來。給UI設計光澤在iOS 7中看起來就過期了。

若是用了拋光或是發亮按鈕,你就得從新設計UI了。問問本身,這個UI在雜誌上打印出來會是什麼樣子的。你得像印刷業的設計師那樣考慮問題,而不是軟件業的設計師。

2.7.3 支持iOS6

寫向後兼容iOS 6的代碼要比之前難,由於iOS 7是其誕生以來的一次大升級。若是你的應用須要支持iOS 6,首先讓iOS 6的應用跟iOS 7的外觀相似,這意味着並不是要在iOS 7中用扁平按鈕卻在iOS 6中用拋光按鈕,而是把iOS 6的按鈕也變扁平。首先改變iOS 6版本的設計,使其看起來像iOS 7版本。對結果滿意後,再添加iOS 7獨有的特性。

1. 應用圖標

iOS 7使用的圖標大小和iOS 6不一樣,對於iPhone應用是120×120,對於iPad應用是152×152。你得爲應用更換這些略大的圖標,避免使用拋光或者發亮,「Icon already includes gloss effects (UIPrerenderedIcon)」這個設置在iOS 7下不起做用,可能最終會廢棄。

2. 啓動圖

啓動圖如今應該是480點高(對於iPhone 5來講是568)。iOS 7中啓動圖會渲染在狀態欄下面,若是你用的啓動圖過短,屏幕底部會出現黑邊。

3. 狀態欄

iOS 7中的狀態欄是半透明的,會將其背後的內容模糊。在iOS 6版本的應用中,應該用拋光不那麼多的設計圖(甚至徹底沒有光澤)確保狀態欄是扁平的。在iOS 7中,視圖控制器會延伸到全屏,位於狀態欄下面。在iOS 6版本的應用中,能夠把狀態欄的樣式改成UIStatusBarStyleBlackTranslucent來模擬這種行爲。

4. 導航欄

iOS 7中的導航欄默認也是半透明的,並且沒有陰影,底部邊界卻是有一條細線。能夠考慮爲iOS 6版本的應用添加相似的效果來取代陰影。

在iOS 6中,設置tintColor會改變導航欄的顏色,要在iOS 7中獲得一樣的效果,須要設置barTintColor。導航欄上的返回按鈕也變了,之前是帶邊框的按鈕,如今則是箭頭和文字。記住,就算是默認按鈕也不帶邊框了,並且UIButtonTypeRoundedRect也廢棄了。在iOS 6版本的應用中,能夠用導航欄的外觀代理協議(appearance proxy protocol )來自定義返回按鈕,併爲返回按鈕設置相似於iOS 7版本的圖片。

導航欄的背景圖一般是320×44,有時候開發者可能會用略高的帶陰影的導航欄。在iOS 7中,導航欄的背景圖延伸到了狀態欄下方,而不是像iOS 6那樣在視圖控制器上方。避免使用高於44點的導航欄背景圖。你可能得從新設計背景圖而且考慮用別的辦法添加陰影。iOS 6爲UINavigationBar引入了shadowImage屬性,能夠用這個屬性設置導航欄陰影。

5. 工具欄

工具欄也是半透明的,不過更重要的是工具欄上的按鈕沒有邊框。若是按鈕很少於3個,能夠考慮用文本按鈕而不是圖片按鈕。好比iOS 7的音樂應用中的正在播放頁面用文本按鈕表示重複、隨機和建立(如圖2-3所示)。

【插入P29圖1】

圖2-3 iOS 7中控制按鈕的截圖

6. 視圖控制器

在iOS 7中,全部視圖控制器都是全屏佈局的。能夠在iOS 7中支持新佈局,在iOS 6中保留舊佈局,可是應用看起來會有點過期。要擁抱變化,在iOS 6版本中用全屏佈局。將視圖控制器的wantsFullscreenLayout屬性設置成YES就能夠在iOS 6中實現這一點。注意,這個屬性在iOS 7中廢棄了,並且在iOS 7中將這個屬性設置成NO的行爲是未定義的。

在iOS 7中也可使用不透明的條欄,這能夠經過Interface Builder的選項控制視圖在半透明/不透明條欄下方的樣子,如圖2-4所示。

【插入P29圖2】

圖2-4 Interface Builder中將視圖延伸到半透明條欄下方的選項

Interface Builder的nib文件中還有Top Layout Guide和Bottom Layout Guide(只有打開自動佈局纔有),也能夠用這些引導點設置約束條件。因此開發者可讓按鈕老是離Top Layout Guide50個點。

7. 表格視圖控制器

表格視圖控制器,尤爲是分組表格視圖樣式,再也不有內嵌效果了。分割線變成了內嵌的,從圖片開始,到屏幕邊緣結束。單元分割線變細了,顏色也變淺了。

section頭顏色也變淺了,並且是純色,再也不是漸變色了。在iOS 7版本的應用中能夠給sectionIndexBackgroundColor設置值來改變顏色。在iOS 6中,只能在tableView:viewForHeaderInSection:委託方法中返回外觀和iOS 7版本相似的視圖。

還有一個重要的變化是選擇樣式。iOS 6提供了兩種樣式:藍色和灰色。用內置樣式時,文本的前景色會從黑色變成白色。在iOS 7中不會這樣,高亮色只是一種淺灰色,覆蓋UITableViewCell子類的setSelected:animated:setHighlighted:animated:能夠模擬這種行爲。

默認的滑動刪除手勢之前是從左向右滑,如今是從右向左滑。若是開發者正考慮在表格視圖單元中用從右向左滑的手勢來顯示菜單或作一個動做,就得考慮用別的方法來實現了。

8. 拖動手勢

iOS 7默認在全部應用中使用兩種拖動手勢,第一種是UIScreenEdgePanGestureRecognizer,在導航控制器中,從屏幕邊緣滑動可讓用戶回到上一個視圖。這個行爲是默認的。若是你在使用像Facebook的舊版應用那樣的漢堡菜單(俗稱側滑菜單或者側滑面板),就得考慮關掉顯示菜單的手勢。事實上,隨着iOS 7的發佈,Facebook徹底拋棄了漢堡菜單,採用了選項卡欄。第二種手勢是從屏幕底部拖動的手勢,能夠顯示控制中心。若是你的應用使用了相似的手勢來調用某個功能,就得從新設計界面了。

9. 警告框和操做列表

警告框和操做列表老是使用系統的默認樣式,除非開發者建立本身的。若是有自定義的警告框,能夠考慮加入UIMotionEffect以便讓其看起來像是浮在視圖控制器上方。在iOS 6中創建層次概念要靠陰影,而在iOS 7中則用運動效果。在iOS 6中模擬運動效果很難。除非願意花費時間和精力,不然就在iOS 6中保留UI元素的陰影吧。

2.8 小結

本章介紹了新的UI範式,還有新設計背後的深層次緣由,而且深刻講解了iOS 7中不一樣的UI相關的技術。最後,咱們介紹瞭如何將應用遷移到iOS 7,而且(可選地)維持向後兼容性。要作到寫出在iOS 6和iOS 7上都能工做的代碼而且外觀在兩個系統上看起來都很好是很難的(至少是相對而言)。若是業務容許你投入時間和資源,那就作吧。不然,把精力集中在iOS 7每一個可能的功能上,讓應用脫穎而出。

iOS 7爲開發者提供了在App Store大獲成功的機遇,舉幾個例子:iOS 7專用的待辦事項應用,iOS 7專用的Twitter客戶端,iOS 7專用的日曆應用。理解了iOS 7的UI範式,是時候大幹一把了。

相關文章
相關標籤/搜索