iOS7中容易被忽視的新特性

原文:Easily Overlooked New Features in iOS 7html

 

iOS7到如今已經發布了有一段時間了。相信你如今已經瞭解了它那些開創性的視覺設計,已經瞭解了它的新的API,好比說SpirteKit,UIKit Dynamics以及TextKit,做爲開發者,也極可能已經在使用Xcode5進行開發了。ios

 

然而,它新穎以及備受爭議的特性是發佈,讓iOS7成爲iOS系統史上最大的發佈之一。除非你是那種用整晚的時間閱讀iOS7更新內容的那種人,那麼就可能會忽視掉一兩個新的變化。objective-c

 

在本篇文章中咱們彙總了一份較完備的iOS7重要且有趣的新變化。如今讓咱們一塊兒來看看是否有一些新變化你之前沒有注意到呢?api

 

壞消息,好消息,以及很是好的消息網絡

iOS7有一些壞消息,一些好消息,還有一些很是好的消息。app

 

壞消息:iOS7中有一些可能會對app形成破壞性的變化,你必需要了解。若是你還不知道這些變化的話,那麼你就須要好好看看他們了,由於當他們在iOS7上運行的時候可能會形成app崩潰!框架

 

好消息:有一些你熟悉的特性和API在iOS7中獲得了優化——可是還有一些其餘的特性被遺棄了。花點時間來看看這些變化,對你app的升級來講是個很好的投資。less

 

很是好的消息iOS7的發佈確實震動了手機開發世界,隨着這個重大事件的發生,隨之而來的也有一系列新功能,它們可能會給你現有app帶來新特點,也可能成爲未來開發的app創新的觸發劑。ide

 

本篇文章蒐羅了iOS7容易忽略的一些特色,將它們分爲了以上三類。如下的列表,若是有感興趣的內容能夠直接跳過去看,也能夠按照文章的順序來了解全部的變化。函數

 

 壞消息:能夠致使app崩潰的變化

1.已禁用-[UIDevice uniqueIdentifier]

2.UIPasteboard由共享變爲沙盒化了

3.MAC地址不能再用來識別設備

4.iOS如今要求app如需使用麥克風,須要徵得用戶贊成

 

好消息:性能提升以及被遺棄的功能

5.-[NSArray firstObject]的實現

6.增長了instancetype

7.設置UIImage的渲染模式:UIImage.renderingMode

8.tintColor VS barTintColor

9.去掉了紋理顏色

10.UIButtonTypeRoundRect被UIButtonTypeSystem取代了

 

很是好的消息:新功能

11.檢查無線路由是否可用

12.瞭解蜂窩網絡

13.經過iCloud同步用戶設備的密碼

14.使用NSAttributedString顯示HTML

15.使用原生的Base64

16.使用UIApplicationUserDidTakeScreenshotNotification來檢查截圖

17.實現多語言語音合成

18.使用了新的手勢識別

19.使用UIScrollViewKeyboardDismissMode實現了Message app的行爲

20.使用Core Image來檢測眨眼以及微笑

21.給UITextView增長了連接

 

壞消息:能夠致使app崩潰的變化

這個部分的變化你可能在瞭解iOS7的時候已經注意到了,可是你也許沒有意識到這些變化的程度,以及它們如何可能會影響你的app。事實上這些變化都和用戶隱私相關,而你應該知道對蘋果來講用戶隱私有多麼重要!

 

1.已禁用-[UIDevice uniqueIdentifier]

蘋果老是把用戶的隱私看的很重要。-[UIDevice uniqueIdentifier]在iOS5實際在iOS5的時候已經被遺棄了,可是iOS7中已經徹底的禁用了它。Xcode5甚至不會容許你編譯包含了指引到-[UIDevice uniqueIdentifier]的app。此外,iOS7以前的使用了-[UIDevice uniqueIdentifier] 的app若是在iOS7上運行,它不會返回設備的UUID,而是會返回一串字符串,以FFFFFFFF開頭,跟着-[UIDevice identifierForVendor]的十六進制值。

 

2.UIPasteboard由共享變爲沙盒化了

 UIPasteboard過去是用來作app之間的數據分享的。UIPasteboard本無問題,可是開發者開始使用它來存儲標識符,和其餘的相關app分享這些標識符的時候問題就出現了。有一個使用這種把戲的就是OpenUDID。

 

在iOS7中,使用 +[UIPasteboard pasteboardWithName:create:]和 +[UIPasteboard pasteboardWithUniqueName]建立剪貼板,並且只對相同的app group可見,這樣就讓OpenUDID不那麼有用了。

 

3.MAC地址不能再用來設別設備

 

如今仍可使用這個MAC

 

還有一個生成iOS設備惟一標示符的方法是使用iOS設備的Media Access Control(MAC)地址。一個MAC地址是一個惟一的號碼,它是物理網絡層級方面分配給網絡適配器的。這個地址蘋果還有其餘的名字,好比說是硬件地址(Hardware Address)或是Wifi地址,都是指一樣的東西。

 

有不少工程和框架都使用這個方法來生成惟一的設備ID。好比說ODIN。然而,蘋果並不但願有人經過MAC地址來分辨用戶,因此若是你在iOS7系統上查詢MAC地址,它如今只會返回02:00:00:00:00:00。

 

如今蘋果明確的代表你應該使用-[UIDevice identifierForVendor]或是-[ASIdentifierManager advertisingIdentifier]來做爲你框架和應用的惟一標示符。坦白的來講,應對這些變化也不是那麼的難,見如下代碼片斷:

NSString *identifierForVendor = [[UIDevice currentDevice].identifierForVendor UUIDString]; NSString *identifierForAdvertising = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];

每種方法都適配一種特別的用法:

identifierForVendor對供應商來講是惟一的一個值,也就是說,由同一個公司發行的的app在相同的設備上運行的時候都會有這個相同的標識符。然而,若是用戶刪除了這個供應商的app而後再從新安裝的話,這個標識符就會不一致。

 

advertisingIdentifier會返回給在這個設備上全部軟件供應商相同的 一個值,因此只能在廣告的時候使用。這個值會由於不少狀況而有所變化,好比說用戶初始化設備的時候便會改變。

 

若是你想了解更多的信息,你能夠看看這篇文章

 

4.iOS如今要求app如需使用麥克風,須要徵得用戶贊成

之前若是app須要使用用戶的位置,通信錄,日曆,提醒以及照片,接受推送消息,使用用戶的社交網絡的時候須要徵得用戶的贊成。如今在iOS7當中,使用麥克風也須要取得用戶贊成了。若是用戶不容許app使用麥克風的話,那麼須要使用麥克風的app就不能接收不到任何聲音。

 

如下的代碼是用來查詢用戶是否容許app使用麥克風:

//第一次調用這個方法的時候,系統會提示用戶讓他贊成你的app獲取麥克風的數據 // 其餘時候調用方法的時候,則不會提醒用戶 // 而會傳遞以前的值來要求用戶贊成 [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {     if (granted) {         // 用戶贊成獲取數據     } else {         // 能夠顯示一個提示框告訴用戶這個app沒有獲得容許?     } }];

你同時還要注意,若是你在得到用戶的贊成以前使用任何方法來使用麥克風的話,會引發iOS系統彈出如下警示欄:

 

好消息:性能提升以及被遺棄的功能

以上就是一些重要的更新,他們可能會讓你如今的app崩潰。而後,還有一些變化可能會對你的app形成影響,可是你不會在第一時間發現這些變化。

 

5.-[NSArray firstObject]的實現

-[NSArray firstObject]多是Objective-C中被調用作多的API。在Open Radar上一個簡單的調查顯示有一些需求蘋果已經作了記錄。好消息是如今這些需求已經獲得瞭解決。. firstObject的使用能夠追溯到iOS4.0,可是那時僅僅是一個私有方法。在iOS7之前,工程師用下面的方式來使用它:

 

NSArray *arr = @[]; id item = [arr firstObject]; // 以前你須要作如下工做 id item = [arr count] > 0 ? arr[0] : nil;

由於上面的方式很日常,有些人將它做爲一個類增長到NSArray中,而後建立他們本身的firstObject方法。在Github上作一個快速搜索你能夠看到過去這種方式是有多麼的經常使用。

 

 這個方法的問題是這個方法的名字必須是惟一的,不然的話這個方法所引起的問題沒法預估。請確保檢查你是否有任何自定義的代碼在NSArray上實現了firstObject,若是有的話看看它是不是必須的,不是必須的話就把它所有移除。

 

6.增長了instancetype

instancetype讓iOS7API變得更加難懂。蘋果改變了大部分 initializer和簡易構造函數(convenience constructors),用instancetype代替id做返回類型。可是這個instancetype是什麼呢?

 

instancetype用來在聲明一個方法時告訴編譯器其返回類型,它表示返回調用該方法的類的對象。這比以前返回id的一般作法要好,編譯器能夠對返回類型作一些檢查,若是出現錯誤,在編譯時就能提醒你,而不是在程序運行時發生崩潰。同時,在調用子類方法時,使用它還能夠省去對返回值的強制類型轉換,編譯器可以正確推斷方法的返回值類型。

 

要說到instancetaype的缺點和優勢嗎?基本上,在任何可能的狀況下均可以使用它。

 

若是須要更多關於instancetype的信息,你能夠看看這篇文章

 

 7.設置UIImage的渲染模式:UIImage.renderingMode

着色(Tint Color)是iOS7界面中的一個重大改變,你能夠設置一個UIImage在渲染時是否使用當前視圖的Tint Color。UIImage新增了一個只讀屬性:renderingMode,對應的還有一個新增方法:imageWithRenderingMode:,它使用UIImageRenderingMode枚舉值來設置圖片的renderingMode屬性。該枚舉中包含下列值:

UIImageRenderingModeAutomatic // 根據圖片的使用環境和所處的繪圖上下文自動調整渲染模式。 UIImageRenderingModeAlwaysOriginal // 始終繪製圖片原始狀態,不使用Tint Color。 UIImageRenderingModeAlwaysTemplate // 始終根據Tint Color繪製圖片,忽略圖片的顏色信息。

 

renderingMode屬性的默認值是UIImageRenderingModeAutomatic,即UIImage是否使用Tint Color取決於它顯示的位置。其餘狀況能夠看下面的圖例

 

如下的代碼說明了使用一個既定的rendering模式建立圖片是多麼簡單:

UIImage *img = [UIImage imageNamed:@"myimage"]; img = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

 

8.tintcolor VS barTintColor

iOS7中你可使用一個給定的顏色,甚至是記入顏色主題來給整個app着色,幫助你的app脫穎而出。設置app的tint color很簡答,只要使用UIView的新屬性tintColor便可。

 

這個屬性是否聽上去很熟悉呢?應該很熟悉,有些類,好比說UINaviagtionBar,UISearchBar,UITabBar以及UIToolbar已經有了這麼命名的屬性。他們如今有了一個新的屬性:barTintColor。

 

爲了不使用新屬性的時候犯錯誤,若是你的appp須要支持iOS6之前的系統的時候,請檢查一下。

UINavigationBar *bar = self.navigationController.navigationBar; UIColor *color = [UIColor greenColor]; if ([bar respondsToSelector:@selector(setBarTintColor:)]) { // iOS 7+     bar.barTintColor = color; } else { // what year is this? 2012?     bar.tintColor = color; }

 9.去掉了紋理顏色

 

紋理顏色?對,再也不使用他們了。不能再建立能夠展示紋理的顏色。根據UIInterface.h文件中的註釋,-[UIColor groupTableViewBackgroundColor]應該是要在iOS6當中即被刪除了,可是它僅僅只是不像以前那樣返回紋理顏色了。然而,如下的顏色在iOS7當中被刪除了:

+ (UIColor *)viewFlipsideBackgroundColor; + (UIColor *)scrollViewTexturedBackgroundColor; + (UIColor *)underPageBackgroundColor;

 

10.UIButtonTypeRoundRect被UIButtonTypeSystem取代了

 

在iOS開發剛開始就陪伴着你的老朋友如今也被刪除了,它就是UIButtonTypeRoundRect ,被新的UIButtonTypeSystem取代了。

 

很是好的消息:新功能

若是每次iOS系統的發佈都沒有一些新的功能會是什麼樣子?這些新功能相信大部分開發者已經知道了,你可能會發現一些新穎的方式將它們整合到你的app中去!

 

11.檢查無線路由是否可用

定製一個視頻播放器的能力在iOS版本每次的發佈中一直有所進步。好比說,在iOS6以前,你不能在MPVolumeView中改變AirPlay的icon。

 

在iOS7當中,你能夠經過AirPlay,藍牙或是其餘的虛線機制瞭解是否有一個遠程的設備可用。瞭解它的話,就可讓你的app在恰當的時候作恰當的事,好比說,在沒有遠程設備的時候就不顯示AirPlay的icon。

 

如下是新增長到MPVolumeView的新屬性和推送

@property (nonatomic, readonly) BOOL wirelessRoutesAvailable; //  是否有設備能夠鏈接的無線線路? @property (nonatomic, readonly) BOOL wirelessRouteActive; // 設備如今是否鏈接上了網絡 NSString *const MPVolumeViewWirelessRoutesAvailableDidChangeNotification; NSString *const MPVolumeViewWirelessRouteActiveDidChangeNotification;

 

12.瞭解蜂窩網絡

在iOS7以前,是使用Reachability來檢測設備是否鏈接到WWAN或是Wifi的。iOS7在這個基礎上更進了一步,它會告訴你的設備鏈接上的是那種蜂窩網絡,好比說是Edge網絡,HSDPA網絡,或是LTE網絡。告訴用戶他們鏈接上的是哪一種網絡能夠優化用戶體驗,由於這樣他們會知道網速如何,不會去請求須要高網速的網絡請求。

 

這是CTTelephonyNetworkInfo的部分功能,它是CoreTelephony框架的一部分。iOS7還增長了currentRadioAccessTechnology屬性和CTRadioAccessTechnologyDidChangeNotification到這個類。還有一些新的字符串常量來定義可能的值,好比說是CTRadioAccessTechnologyLTE。

 

如下代碼告訴你在app delegate中如何使用這個新功能:

@import CoreTelephony.CTTelephonyNetworkInfo; // new modules syntax!  @interface AppDelegate ()  // we need to keep a reference to the CTTelephonyNetworkInfo object, otherwise the notifications won't be fired! @property (nonatomic, strong) CTTelephonyNetworkInfo *networkInfo;   @end   @implementation ViewController    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   // whatever stuff your method does...     self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];   NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology);   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:CTRadioAccessTechnologyDidChangeNotification object:nil];     // whatever stuff your method does... }   - (void)radioAccessChanged {   NSLog(@"Now you're connected via %@", self.networkInfo.currentRadioAccessTechnology); }   @end

注意:研究一下CTTelephonyNetworkInfo.h 文件來看看是否有其餘無線網絡類型的的字符串常量。若是設備沒有連上的話,currentRadioAccessTechnology 則會返回nil。

 

13.經過iCloud同步用戶設備的密碼

iOS7以及Mavericks增長了iCloud Keychain來提供密碼,以及iCloud中一些敏感數據的同步。開發者能夠經過keychain中的kSecAttrSynchronizable key來遍歷dictionary對象。

 

因爲直接處理keychain比較難,封裝庫提供了一個簡單的處理keychain的方法。SSKeychain封裝庫多是最有名的的一個,做爲一種福利,如今它支持在iCloud同步。

 

如下代碼片斷顯示瞭如何使用SSKeychain:

#import <SSKeychain.h>   - (BOOL)saveCredentials:(NSError **)error {     SSKeychainQuery *query = [[SSKeychainQuery alloc] init];     query.password = @"MySecretPassword";     query.service = @"MyAwesomeService";     query.account = @"John Doe";     query.synchronizable = YES;     return [query save:&error]; }   - (NSString *)savedPassword:(NSError **)error {     SSKeychainQuery *query = [[SSKeychainQuery alloc] init];     query.service = @"MyAwesomeService";     query.account = @"John Doe";     query.synchronizable = YES;     query.password = nil;     if ([query fetch:&error]) {         return query.password;     }     return nil; }

不要忘記CocoaPods是快速便捷安裝SSKeychian的好方法。

 

14.使用NSAttributedString顯示HTML

在app中使用Webviews有時會讓人很是沮喪,即便只是顯示少許的HTMLneirong ,Webviews也會消耗大量的內容。如今iOS7讓這些變得簡單了,你能夠從用少許代碼在HTML文件中建立一個NSAttributedString,好比:

NSString *html = @"<bold>Wow!</bold> Now <em>iOS</em> can create <h3>NSAttributedString</h3> from HTMLs!"; NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};   NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUTF8StringEncoding] options:options documentAttributes:nil error:nil];

 

如今你能夠在任意的UIKit對象上使用NSAttributedString 了,好比說是一個UILabel或是一個UITextField,見如下代碼:

#import <SSKeychain.h>   - (BOOL)saveCredentials:(NSError **)error {     SSKeychainQuery *query = [[SSKeychainQuery alloc] init];     query.password = @"MySecretPassword";     query.service = @"MyAwesomeService";     query.account = @"John Doe";     query.synchronizable = YES;     return [query save:&error]; }   - (NSString *)savedPassword:(NSError **)error {     SSKeychainQuery *query = [[SSKeychainQuery alloc] init];     query.service = @"MyAwesomeService";     query.account = @"John Doe";     query.synchronizable = YES;     query.password = nil;     if ([query fetch:&error]) {         return query.password;     }     return nil;

 注意:NSHTMLTextDocumentType 只是NSDocumentTypeDocumentAttribute key一種可能的值。你還可使用NSPlainTextDocumentType,NSRTFTextDocumentType或是NSRTFDTextDocumentType。

 

 你還能夠從NSAttributedString中建立一個HTML字符串,以下:

NSAttributedString *attrString; // from previous code NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};   NSData *htmlData = [attrString dataFromRange:NSMakeRange(0, [attrString length]) documentAttributes:options error:nil]; NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];

如今你估計在app中會更多的使用HTML了。

 

15.使用原生的Base64

Base64是使用ASCII碼顯示二進制數據的一種流行方法。直到如今,開發者還不得不使用開源的工具來編碼解碼Base64的內容。

 

如今iOS7引入瞭如下四種新的NSData方法來操做Base64編碼的數據:

// From NSData.h   /* Create an NSData from a Base-64 encoded NSString using the given options. By default, returns nil when the input is not recognized as valid Base-64. */ - (id)initWithBase64EncodedString:(NSString *)base64String options:(NSDataBase64DecodingOptions)options;   /* Create a Base-64 encoded NSString from the receiver's contents using the given options. */ - (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options;   /* Create an NSData from a Base-64, UTF-8 encoded NSData. By default, returns nil when the input is not recognized as valid Base-64. */ - (id)initWithBase64EncodedData:(NSData *)base64Data options:(NSDataBase64DecodingOptions)options;   /* Create a Base-64, UTF-8 encoded NSData from the receiver's contents using the given options. */ - (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options;

 

這些方法能夠幫助你輕易的將NSData對象轉化爲Base64,或者將Base64轉化爲NSData object。見如下的例子:

 NSData* sampleData = [@"Some sample data" dataUsingEncoding:NSUTF8StringEncoding];   NSString * base64String = [sampleData base64EncodedStringWithOptions:0]; NSLog(@"Base64-encoded string is %@", base64String); // prints "U29tZSBzYW1wbGUgZGF0YQ=="   NSData* dataFromString = [[NSData alloc] initWithBase64EncodedString:base64String options:0]; NSLog(@"String is %@",[NSString stringWithUTF8String:[dataFromString bytes]]); // prints "String is Some sample data"

 

若是你須要支持iOS6或者更早之前的系統,你可使用如下兩個方法:

 
  1. /* These methods first appeared in NSData.h on OS X 10.9 and iOS 7.0. They are deprecated in the same releases in favor of 
    the methods in the <code>NSDataBase64Encoding</code> category. However, these methods have existed for several releases, so 

  2. they may be used for applications targeting releases prior to OS X 10.9 and iOS 7.0. 

  3. */ 

  4. - (id)initWithBase64Encoding:(NSString *)base64String; 

  5. - (NSString *)base64Encoding; 

  

16.使用UIApplicationUserDidTakeScreenshotNotification來檢查截圖

 在iOS7以前,像Snapshot或是Facebook Poke這樣的app是使用一些很精巧的方法來檢測用戶是否有截圖。然而,iOS7提供一個嶄新的推送方法:UIApplicationUserDidTakeScreenshotNotification。只要像往常同樣訂閱便可知道何時截圖了。

 

注意:UIApplicationUserDidTakeScreenshotNotification 將會在截圖完成以後顯示。如今在截圖截取以前沒法獲得通知。但願蘋果會在iOS8當中增長UIApplicationUserWillTakeScreenshotNotification。

 

17.實現多語言語音合成

若是可讓app說話會不會很好呢?iOS7加入了兩個新類:AVSpeechSynthesizer 以及AVSpeechUtterance。這兩個類能夠給你的app發聲。頗有意思不是嗎?有多種語言可供選擇——Siri不會說的語言也有,好比說巴西葡萄牙語。

 

使用這兩個類給app提供語言合成的功能很是簡單。AVSpeechUtterance 表明你想說什麼,如何說。AVSpeechSynthesizer 用來發出這些聲音,見如下代碼片斷:

AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init]; AVSpeechUtterance *utterance =    [AVSpeechUtterance speechUtteranceWithString:@"Wow, I have such a nice voice!"]; utterance.rate = AVSpeechUtteranceMaximumSpeechRate / 4.0f; utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-US"]; // defaults to your system language [synthesizer speakUtterance:utterance];

 

18.使用了新的UIScreenEdgePanGestureRecognizer 

UIScreenEdgePanGestureRecognizer 繼承自UIPanGestureRecognizer ,它可讓你從屏幕邊界便可檢測手勢。

 

使用新的手勢識別器很簡單,見如下:

UIScreenEdgePanGestureRecognizer *recognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleScreenEdgeRecognizer:)]; recognizer.edges = UIRectEdgeLeft; // accept gestures that start from the left; we're probably building another hamburger menu! [self.view addGestureRecognizer:recognizer];

 

19.使用UIScrollViewKeyboardDismissMode實現了Message app的行爲

像Messages app同樣在滾動的時候可讓鍵盤消失是一種很是好的體驗。然而,將這種行爲整合到你的app很難。幸運的是,蘋果給UIScrollView添加了一個很好用的屬性keyboardDismissMode,這樣能夠方便不少。

 

如今僅僅只須要在Storyboard中改變一個簡單的屬性,或者增長一行代碼,你的app能夠和辦到和Messages app同樣的事情了。

 

這個屬性使用了新的UIScrollViewKeyboardDismissMode enum枚舉類型。這個enum枚舉類型可能的值以下:

UIScrollViewKeyboardDismissModeNone        // the keyboard is not dismissed automatically when scrolling UIScrollViewKeyboardDismissModeOnDrag      // dismisses the keyboard when a drag begins UIScrollViewKeyboardDismissModeInteractive // the keyboard follows the dragging touch off screen, and may be pulled upward again to cancel the dismiss

 

如下是讓鍵盤能夠在滾動的時候消失須要設置的屬性:

 

 

20.使用Core Image來檢測眨眼以及微笑

iOS給Core Image增長了兩種人臉檢測功能:CIDetectorEyeBlink以及CIDetectorSmile。這也就是說你如今能夠在照片中檢測微笑以及眨眼。

 

如下是在app中使用它的方法:

UIImage *image = [UIImage imageNamed:@"myImage"]; CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace                                           context:nil                                           options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];   NSDictionary *options = @{ CIDetectorSmile: @YES, CIDetectorEyeBlink: @YES };   NSArray *features = [detector featuresInImage:image.CIImage options:options];   for (CIFaceFeature *feature in features) {     NSLog(@"Bounds: %@", NSStringFromCGRect(feature.bounds));       if (feature.hasSmile) {     NSLog(@"Nice smile!");     } else {     NSLog(@"Why so serious?");     }     if (feature.leftEyeClosed || feature.rightEyeClosed) {     NSLog(@"Open your eyes!");     } }

21.給UITextView增長了連接

如今在iOS添加你本身的Twitter帳戶更加簡單了,如今你能夠給一個NSAttributedString增長連接了,而後當它被點擊的時候喚起一個定製的action。

 

首先,建立一個NSAttributedString而後增長給它增長一個NSLinkAttributeName 屬性,見如下:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"This is an example by @marcelofabri_"]; [attributedString addAttribute:NSLinkAttributeName                          value:@"username://marcelofabri_"                          range:[[attributedString string] rangeOfString:@"@marcelofabri_"]];     NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor greenColor],                                  NSUnderlineColorAttributeName: [UIColor lightGrayColor],                                  NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};   // assume that textView is a UITextView previously created (either by code or Interface Builder) textView.linkTextAttributes = linkAttributes; // customizes the appearance of links textView.attributedText = attributedString; textView.delegate = self;

 

這樣就可讓連接在文本中顯示。然而,你也能夠控制當連接被點擊的時候會發生什麼,實現這個可使用UITextViewDelegate協議的新的shouldInteractWithURL方法,就像這樣:

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {     if ([[URL scheme] isEqualToString:@"username"]) {         NSString *username = [URL host];          // do something with this username         // ...         return NO;     }     return YES; // let the system open this URL }

 

如今這些新功能就介紹完了。

相關文章
相關標籤/搜索