iOS7中容易被忽視的新特性

jopen 10年前發布 | 36K 次閱讀 iOS7 iOS開發 移動開發
 
iOS7到現在已經發布了有一段時間了。相信你現在已經了解了它那些開創性的視覺設計,已經了解了它的新的API,比如說SpirteKit,UIKit Dynamics以及TextKit,作為開發者,也很可能已經在使用Xcode5進行開發了。
 
然而,它新穎以及備受爭議的特性,讓iOS7成為iOS系統史上最大的發布之一。除非你是那種用整晚的時間閱讀iOS7更新內容的那種人,那么就可能會忽視掉一兩個新的變化。
 
在本篇文章中我們匯總了一份較完備的iOS7重要且有趣的新變化。現在讓我們一起來看看是否有一些新變化你以前沒有注意到呢?
 
壞消息,好消息,以及非常好的消息
iOS7有一些壞消息,一些好消息,還有一些非常好的消息。
 
壞消息:iOS7中有一些可能會對app造成破壞性的變化,你必須要了解。如果你還不知道這些變化的話,那么你就需要好好看看他們了,因為當他們在iOS7上運行的時候可能會造成app崩潰!
 
好消息:有一些你熟悉的特性和API在iOS7中得到了優化——但是還有一些其他的特性被遺棄了。花點時間來看看這些變化,對你app的升級來說是個很好的投資。
 
非常好的消息 iOS7的發布確實震動了手機開發世界,隨著這個重大事件的發生,隨之而來的也有一系列新功能,它們可能會給你現有app帶來新特色,也可能成為將來開發的app創新的觸發劑。
 
本篇文章搜羅了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地址不能再用來設別設備
 
iOS7中容易被忽視的新特性
現在仍可以使用這個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]來作為你框架和應用的唯一標示符。坦白的來說,應對這些變化也不是那么的難,見以下代碼片段:
    
  1. NSString *identifierForVendor = [[UIDevice currentDevice].identifierForVendor UUIDString]; 
  2. NSString *identifierForAdvertising = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString]; 
每種方法都適配一種特別的用法:
identifierForVendor對供應商來說是唯一的一個值,也就是說,由同一個公司發行的的app在相同的設備上運行的時候都會有這個相同的標識符。然而,如果用戶刪除了這個供應商的app然后再重新安裝的話,這個標識符就會不一致。
 
advertisingIdentifier會返回給在這個設備上所有軟件供應商相同的 一個值,所以只能在廣告的時候使用。這個值會因為很多情況而有所變化,比如說用戶初始化設備的時候便會改變。
 
如果你想了解更多的信息,你可以看看 這篇文章
 
4.iOS現在要求app如需使用麥克風,需要征得用戶同意
以前如果app需要使用用戶的位置,通訊錄,日歷,提醒以及照片,接受推送消息,使用用戶的社交網絡的時候需要征得用戶的同意。現在在iOS7當中,使用 麥克風也需要取得用戶同意了。如果用戶不允許app使用麥克風的話,那么需要使用麥克風的app就不能接收不到任何聲音。
 
以下的代碼是用來查詢用戶是否允許app使用麥克風:
    
  1. //第一次調用這個方法的時候,系統會提示用戶讓他同意你的app獲取麥克風的數據 
  2. // 其他時候調用方法的時候,則不會提醒用戶 
  3. // 而會傳遞之前的值來要求用戶同意 
  4. [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) { 
  5.     if (granted) { 
  6.         // 用戶同意獲取數據 
  7.     } else { 
  8.         // 可以顯示一個提示框告訴用戶這個app沒有得到允許? 
  9.     } 
  10. }]; 
你同時還要注意,如果你在獲得用戶的同意之前使用任何方法來使用麥克風的話,會引起iOS系統彈出以下警示欄:
iOS7中容易被忽視的新特性
 
好消息:性能提高以及被遺棄的功能
以上就是一些重要的更新,他們可能會讓你現在的app崩潰。然后,還有一些變化可能會對你的app造成影響,但是你不會在第一時間發現這些變化。
 
5.-[NSArray firstObject]的實現
-[NSArray firstObject]可能是Objective-C中被調用做多的API。在Open Radar上一個簡單的調查顯示有一些需求蘋果已經做了記錄。好消息是現在這些需求已經得到了解決。. firstObject的使用可以追溯到iOS4.0,但是那時僅僅是一個私有方法。在iOS7以前,工程師用下面的方式來使用它:
 
    
  1. NSArray *arr = @[]; 
  2. id item = [arr firstObject]; 
  3. // 之前你需要做以下工作 
  4. 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屬 性。該枚舉中包含下列值:
    
  1. UIImageRenderingModeAutomatic // 根據圖片的使用環境和所處的繪圖上下文自動調整渲染模式。 
  2. UIImageRenderingModeAlwaysOriginal // 始終繪制圖片原始狀態,不使用Tint Color。 
  3. UIImageRenderingModeAlwaysTemplate // 始終根據Tint Color繪制圖片,忽略圖片的顏色信息。 
 
renderingMode屬性的默認值是UIImageRenderingModeAutomatic,即UIImage是否使用Tint Color取決于它顯示的位置。其他情況可以看下面的圖例
iOS7中容易被忽視的新特性
 
以下的代碼說明了使用一個既定的rendering模式創建圖片是多么簡單:
    
  1. UIImage *img = [UIImage imageNamed:@"myimage"]; 
  2. img = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 
 
8.tintcolor VS barTintColor
iOS7中你可以使用一個給定的顏色,甚至是記入顏色主題來給整個app著色,幫助你的app脫穎而出。設置app的tint color很簡答,只要使用UIView的新屬性tintColor即可。
 
這個屬性是否聽上去很熟悉呢?應該很熟悉,有些類,比如說UINaviagtionBar,UISearchBar,UITabBar以及UIToolbar已經有了這么命名的屬性。他們現在有了一個新的屬性:barTintColor。
 
為了避免使用新屬性的時候犯錯誤,如果你的appp需要支持iOS6以前的系統的時候,請檢查一下。
    
  1. UINavigationBar *bar = self.navigationController.navigationBar; 
  2. UIColor *color = [UIColor greenColor]; 
  3. if ([bar respondsToSelector:@selector(setBarTintColor:)]) { // iOS 7+ 
  4.     bar.barTintColor = color; 
  5. else { // what year is this? 2012? 
  6.     bar.tintColor = color; 
 9.去掉了紋理顏色
iOS7中容易被忽視的新特性
 
紋理顏色?對,不再使用他們了。不能再創建可以展現紋理的顏色。根據UIInterface.h文件中的注釋,-[UIColor groupTableViewBackgroundColor]應該是要在iOS6當中即被刪除了,但是它僅僅只是不像之前那樣返回紋理顏色了。然而,以 下的顏色在iOS7當中被刪除了:
    
  1. + (UIColor *)viewFlipsideBackgroundColor; 
  2. + (UIColor *)scrollViewTexturedBackgroundColor; 
  3. + (UIColor *)underPageBackgroundColor; 
 
10.UIButtonTypeRoundRect被UIButtonTypeSystem取代了
iOS7中容易被忽視的新特性
 
在iOS開發剛開始就陪伴著你的老朋友現在也被刪除了,它就是UIButtonTypeRoundRect ,被新的UIButtonTypeSystem取代了。
 
非常好的消息:新功能
如果每次iOS系統的發布都沒有一些新的功能會是什么樣子?這些新功能相信大部分開發者已經知道了,你可能會發現一些新穎的方式將它們整合到你的app中去!
 
11.檢查無線路由是否可用
定制一個視頻播放器的能力在iOS版本每次的發布中一直有所進步。比如說,在iOS6之前,你不能在MPVolumeView中改變AirPlay的icon。
 
在iOS7當中,你可以通過AirPlay,藍牙或是其他的虛線機制了解是否有一個遠程的設備可用。了解它的話,就可以讓你的app在恰當的時候做恰當的事,比如說,在沒有遠程設備的時候就不顯示AirPlay的icon。
 
以下是新增加到MPVolumeView的新屬性和推送
    
  1. @property (nonatomic, readonly) BOOL wirelessRoutesAvailable; //  是否有設備可以連接的無線線路? 
  2. @property (nonatomic, readonly) BOOL wirelessRouteActive; // 設備現在是否連接上了網絡 
  3. NSString *const MPVolumeViewWirelessRoutesAvailableDidChangeNotification; 
  4. NSString *const MPVolumeViewWirelessRouteActiveDidChangeNotification;  
 
12.了解蜂窩網絡
在iOS7之前,是使用Reachability來檢測設備是否連接到WWAN或是Wifi的。iOS7在這個基礎上更進了一步,它會告訴你的設備連接上 的是那種蜂窩網絡,比如說是Edge網絡,HSDPA網絡,或是LTE網絡。告訴用戶他們連接上的是哪種網絡可以優化用戶體驗,因為這樣他們會知道網速如 何,不會去請求需要高網速的網絡請求。
 
這是CTTelephonyNetworkInfo的部分功能,它是CoreTelephony框架的一部分。iOS7還增加了 currentRadioAccessTechnology屬性和 CTRadioAccessTechnologyDidChangeNotification到這個類。還有一些新的字符串常量來定義可能的值,比如說是 CTRadioAccessTechnologyLTE。
 
以下代碼告訴你在app delegate中如何使用這個新功能:
    
  1. @import CoreTelephony.CTTelephonyNetworkInfo; // new modules syntax! 
  2.  @interface AppDelegate ()  
  3. // we need to keep a reference to the CTTelephonyNetworkInfo object, otherwise the notifications won't be fired! 
  4. @property (nonatomic, strong) CTTelephonyNetworkInfo *networkInfo; 
  5.   @end 
  6.   
  7. @implementation ViewController  
  8.   
  9. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
  10.   // whatever stuff your method does... 
  11.   
  12.   self.networkInfo = [[CTTelephonyNetworkInfo alloc] init]; 
  13.   NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology); 
  14.   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:
  15. CTRadioAccessTechnologyDidChangeNotification object:nil]; 
  16.   
  17.   // whatever stuff your method does... 
  18.   
  19. - (void)radioAccessChanged { 
  20.   NSLog(@"Now you're connected via %@", self.networkInfo.currentRadioAccessTechnology); 
  21.   
  22. @end 
注意:研究一下CTTelephonyNetworkInfo.h 文件來看看是否有其他無線網絡類型的的字符串常量。如果設備沒有連上的話,currentRadioAccessTechnology 則會返回nil。
 
13.通過iCloud同步用戶設備的密碼
iOS7以及Mavericks增加了iCloud Keychain來提供密碼,以及iCloud中一些敏感數據的同步。開發者可以通過keychain中的kSecAttrSynchronizable key來遍歷dictionary對象。
 
由于直接處理keychain比較難,封裝庫提供了一個簡單的處理keychain的方法。SSKeychain封裝庫可能是最有名的的一個,作為一種福利,現在它支持在iCloud同步。
 
以下代碼片段顯示了如何使用SSKeychain:
    
  1. #import  
  2.   
  3. - (BOOL)saveCredentials:(NSError **)error { 
  4.     SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; 
  5.     query.password = @"MySecretPassword"
  6.     query.service = @"MyAwesomeService"
  7.     query.account = @"John Doe"
  8.     query.synchronizable = YES; 
  9.     return [query save:&error]; 
  10.   
  11. - (NSString *)savedPassword:(NSError **)error { 
  12.     SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; 
  13.     query.service = @"MyAwesomeService"
  14.     query.account = @"John Doe"
  15.     query.synchronizable = YES; 
  16.     query.password = nil; 
  17.     if ([query fetch:&error]) { 
  18.         return query.password; 
  19.     } 
  20.     return nil; 
不要忘記CocoaPods是快速便捷安裝SSKeychian的好方法。
 
14.使用NSAttributedString顯示HTML
在app中使用Webviews有時會讓人非常沮喪,即使只是顯示少量的HTMLneirong ,Webviews也會消耗大量的內容。現在iOS7讓這些變得簡單了,你可以從用少量代碼在HTML文件中創建一個NSAttributedString,比如:
    
  1. NSString *html = @"Wow! Now iOS can create 

    NSAttributedString

     from HTMLs!"
  2. NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}; 
  3.   
  4. NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUTF8StringEncoding] 
  5. options:options documentAttributes:nil error:nil]; 
  6.   
 
現在你可以在任意的UIKit對象上使用NSAttributedString 了,比如說是一個UILabel或是一個UITextField,見以下代碼:
    
  1. #import  
  2.   
  3. - (BOOL)saveCredentials:(NSError **)error { 
  4.     SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; 
  5.     query.password = @"MySecretPassword"
  6.     query.service = @"MyAwesomeService"
  7.     query.account = @"John Doe"
  8.     query.synchronizable = YES; 
  9.     return [query save:&error]; 
  10.   
  11. - (NSString *)savedPassword:(NSError **)error { 
  12.     SSKeychainQuery *query = [[SSKeychainQuery alloc] init]; 
  13.     query.service = @"MyAwesomeService"
  14.     query.account = @"John Doe"
  15.     query.synchronizable = YES; 
  16.     query.password = nil; 
  17.     if ([query fetch:&error]) { 
  18.         return query.password; 
  19.     } 
  20.     return nil; 
  注意:NSHTMLTextDocumentType 只是NSDocumentTypeDocumentAttribute key一種可能的值。你還可以使用NSPlainTextDocumentType,NSRTFTextDocumentType或是 NSRTFDTextDocumentType。
 
 你還可以從NSAttributedString中創建一個HTML字符串,如下:
    
  1. NSAttributedString *attrString; // from previous code 
  2. NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}; 
  3.   
  4. NSData *htmlData = [attrString dataFromRange:NSMakeRange(0, [attrString length]) documentAttributes:options error:nil]; 
  5. NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding]; 
現在你估計在app中會更多的使用HTML了。
 
15.使用原生的Base64
Base64是使用ASCII碼顯示二進制數據的一種流行方法。直到現在,開發者還不得不使用開源的工具來編碼解碼Base64的內容。
 
現在iOS7引入了以下四種新的NSData方法來操作Base64編碼的數據:
    
  1. // From NSData.h 
  2.   
  3. /* Create an NSData from a Base-64 encoded NSString using the given options. By default, returns nil when the input is not recognized
  4.  as valid Base-64. 
  5. */ 
  6. - (id)initWithBase64EncodedString:(NSString *)base64String options:(NSDataBase64DecodingOptions)options; 
  7.   
  8. /* Create a Base-64 encoded NSString from the receiver's contents using the given options. 
  9. */ 
  10. - (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options; 
  11.   
  12. /* 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. 
  13. */ 
  14. - (id)initWithBase64EncodedData:(NSData *)base64Data options:(NSDataBase64DecodingOptions)options; 
  15.   
  16. /* Create a Base-64, UTF-8 encoded NSData from the receiver's contents using the given options. 
  17. */ 
  18. - (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options; 
 
這些方法可以幫助你輕易的將NSData對象轉化為Base64,或者將Base64轉化為NSData object。見以下的例子:
    
  1.  NSData* sampleData = [@"Some sample data" dataUsingEncoding:NSUTF8StringEncoding]; 
  2.   
  3. NSString * base64String = [sampleData base64EncodedStringWithOptions:0]; 
  4. NSLog(@"Base64-encoded string is %@", base64String); // prints "U29tZSBzYW1wbGUgZGF0YQ==" 
  5.   
  6. NSData* dataFromString = [[NSData alloc] initWithBase64EncodedString:base64String options:0]; 
  7. 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 NSDataBase64Encoding 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或是非死book Poke這樣的app是使用一些很精巧的方法來檢測用戶是否有截圖。然而,iOS7提供一個嶄新的推送方 法:UIApplicationUserDidTakeScreenshotNotification。只要像往常一樣訂閱即可知道什么時候截圖了。
 
注意:UIApplicationUserDidTakeScreenshotNotification 將會在截圖完成之后顯示。現在在截圖截取之前無法得到通知。希望蘋果會在iOS8當中增加 UIApplicationUserWillTakeScreenshotNotification。
 
17.實現多語言語音合成
如果可以讓app說話會不會很好呢?iOS7加入了兩個新類:AVSpeechSynthesizer 以及AVSpeechUtterance。這兩個類可以給你的app發聲。很有意思不是嗎?有多種語言可供選擇——Siri不會說的語言也有,比如說巴西葡萄牙語。
 
使用這兩個類給app提供語言合成的功能非常簡單。AVSpeechUtterance 代表你想說什么,如何說。AVSpeechSynthesizer 用來發出這些聲音,見以下代碼片段:
    
  1. AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init]; 
  2. AVSpeechUtterance *utterance =  
  3.   [AVSpeechUtterance speechUtteranceWithString:@"Wow, I have such a nice voice!"]; 
  4. utterance.rate = AVSpeechUtteranceMaximumSpeechRate / 4.0f; 
  5. utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-US"]; // defaults to your system language 
  6. [synthesizer speakUtterance:utterance]; 
 
18.使用了新的UIScreenEdgePanGestureRecognizer 
UIScreenEdgePanGestureRecognizer 繼承自UIPanGestureRecognizer ,它可以讓你從屏幕邊界即可檢測手勢。
 
使用新的手勢識別器很簡單,見以下:
    
  1. UIScreenEdgePanGestureRecognizer *recognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:
  2. @selector(handleScreenEdgeRecognizer:)]; 
  3. recognizer.edges = UIRectEdgeLeft; // accept gestures that start from the left; we're probably building another hamburger menu! 
  4. [self.view addGestureRecognizer:recognizer]; 
 
19.使用UIScrollViewKeyboardDismissMode實現了Message app的行為
像Messages app一樣在滾動的時候可以讓鍵盤消失是一種非常好的體驗。然而,將這種行為整合到你的app很難。幸運的是,蘋果給UIScrollView添加了一個很好用的屬性keyboardDismissMode,這樣可以方便很多。
 
現在僅僅只需要在Storyboard中改變一個簡單的屬性,或者增加一行代碼,你的app可以和辦到和Messages app一樣的事情了。
 
這個屬性使用了新的UIScrollViewKeyboardDismissMode enum枚舉類型。這個enum枚舉類型可能的值如下:
    
  1. UIScrollViewKeyboardDismissModeNone        // the keyboard is not dismissed automatically when scrolling 
  2. UIScrollViewKeyboardDismissModeOnDrag      // dismisses the keyboard when a drag begins 
  3. UIScrollViewKeyboardDismissModeInteractive // the keyboard follows the dragging touch off screen, and may be
  4.  pulled upward again to cancel the dismiss 
 
以下是讓鍵盤可以在滾動的時候消失需要設置的屬性:
 
iOS7中容易被忽視的新特性
 
20.使用Core Image來檢測眨眼以及微笑
iOS給Core Image增加了兩種人臉檢測功能:CIDetectorEyeBlink以及CIDetectorSmile。這也就是說你現在可以在照片中檢測微笑以及眨眼。
 
以下是在app中使用它的方法:
    
  1. UIImage *image = [UIImage imageNamed:@"myImage"]; 
  2. CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace 
  3.                                           context:nil 
  4.                                           options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}]; 
  5.   
  6. NSDictionary *options = @{ CIDetectorSmile: @YES, CIDetectorEyeBlink: @YES }; 
  7.   
  8. NSArray *features = [detector featuresInImage:image.CIImage options:options]; 
  9.   
  10. for (CIFaceFeature *feature in features) { 
  11.     NSLog(@"Bounds: %@", NSStringFromCGRect(feature.bounds)); 
  12.   
  13.     if (feature.hasSmile) { 
  14.     NSLog(@"Nice smile!"); 
  15.     } else { 
  16.     NSLog(@"Why so serious?"); 
  17.     } 
  18.     if (feature.leftEyeClosed || feature.rightEyeClosed) { 
  19.     NSLog(@"Open your eyes!"); 
  20.     } 
21.給UITextView增加了鏈接
現在在iOS添加你自己的推ter賬戶更加簡單了,現在你可以給一個NSAttributedString增加鏈接了,然后當它被點擊的時候喚起一個定制的action。
 
首先,創建一個NSAttributedString然后增加給它增加一個NSLinkAttributeName 屬性,見以下:
    
  1. NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"This is an example by @marcelofabri_"]; 
  2. [attributedString addAttribute:NSLinkAttributeName 
  3.                          value:@"username://marcelofabri_" 
  4.                          range:[[attributedString string] rangeOfString:@"@marcelofabri_"]]; 
  5.   
  6.   
  7. NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor greenColor], 
  8.                                  NSUnderlineColorAttributeName: [UIColor lightGrayColor], 
  9.                                  NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)}; 
  10.   
  11. // assume that textView is a UITextView previously created (either by code or Interface Builder) 
  12. textView.linkTextAttributes = linkAttributes; // customizes the appearance of links 
  13. textView.attributedText = attributedString; 
  14. textView.delegate = self; 
 
這樣就可以讓鏈接在文本中顯示。然而,你也可以控制當鏈接被點擊的時候會發生什么,實現這個可以使用UITextViewDelegate協議的新的shouldInteractWithURL方法,就像這樣:
    
  1. - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange { 
  2.     if ([[URL scheme] isEqualToString:@"username"]) { 
  3.         NSString *username = [URL host];  
  4.         // do something with this username 
  5.         // ... 
  6.         return NO; 
  7.     } 
  8.     return YES; // let the system open this URL 
 
現在這些新功能就介紹完了。
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!