1、关于内存警告ios6中废除了viewDidUnload,viewWillUnload这两个系统回调,收到内存警告时在didReceiveMemoryWarning中进行相关的处理。html
2、关于屏幕旋转一样ios6 废除了shouldAutorotateToInterfaceOrientation这个旋转屏幕的设置接口。必须在两个新接口中设置旋转属性:shouldAutorotate、supportedInterfaceOrientations。收到旋转事件后的处理,一样在willRotateToInterfaceOrientation和didRotateFromInterfaceOrientation中进行。ios
3、UISwitchios6下,新增了如下几个属性,能够设置开关的颜色以及背景图。@property (nonatomic, retain) UIColor *tintColor;web
@property (nonatomic, retain) UIColor *thumbTintColor; 数组
@property (nonatomic, retain) UIImage *onImage; xcode
@property (nonatomic, retain) UIImage *offImage;浏览器
4、UINavigationBarios6新增了,设置阴影图片的属性。安全
1@property (nonatomic, retain) UIImage *shadowImage;服务器
5、UIImage能够在ios6下设置图片的scale比例尺寸了。网络
+ (UIImage *)imageWithData:(NSData *)data scale:(CGFloat)scale; app
- (id)initWithData:(NSData *)data scale:(CGFloat)scale;
6、UIRefreshControl以前苹果官方是没有现成的下拉刷新的控件,都是本身实现或者使用比较成熟的开源库。ios6苹果加入了UIRefreshControl,配合UITableView直接实现下拉刷新。
7、UICollectionView全新的集合控件,应用场景有相似照片墙,瀑布流等。
iOS7新特性
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地址不能再用来设别设备还有一个生成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]来做为你框架和应用的惟一标示符。坦白的来讲,应对这些变化也不是那么的难,见如下代码片断:123NSString *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系统弹出如下警示栏:
5、[NSArray firstObject]的实现-[NSArray firstObject]多是Objective-C中被调用作多的API。在Open Radar上一个简单的调查显示有一些需求苹果已经作了记录。好消息是如今这些需求已经获得了解决。. firstObject的使用能够追溯到iOS4.0,可是那时仅仅是一个私有方法。在iOS7之前,工程师用下面的方式来使用它:12345NSArray *arr = @[];id item = [arr firstObject]; // 在以前你须要作如下工做id item = [arr count] > 0 ? arr[0] : nil;由于上面的方式很日常,有些人将它做为一个类增长到NSArray中,而后建立他们本身的firstObject方法。这个方法的问题是这个方法的名字必须是惟一的,不然的话这个方法所引起的问题没法预估。请确保检查你是否有任何自定义的代码在NSArray上实现了firstObject,若是有的话看看它是不是必须的,不是必须的话就把它所有移除。
6、增长了instancetypeinstancetype让iOS7API变得更加难懂。苹果改变了大部分 initializer和简易构造函数(convenience constructors),用instancetype代替id做返回类型。可是这个instancetype是什么呢?instancetype用来在声明一个方法时告诉编译器其返回类型,它表示返回调用该方法的类的对象。这比以前返回id的一般作法要好,编译器能够对返回类型作一些检查,若是出现错误,在编译时就能提醒你,而不是在程序运行时发生崩溃。同时,在调用子类方法时,使用它还能够省去对返回值的强制类型转换,编译器可以正确推断方法的返回值类型。要说到instancetaype的缺点和优势吗?基本上,在任何可能的状况下均可以使用它。
7、设置UIImage的渲染模式:UIImage.renderingMode着色(Tint Color)是iOS7界面中的一个重大改变,你能够设置一个UIImage在渲染时是否使用当前视图的Tint Color。UIImage新增了一个只读属性:renderingMode,对应的还有一个新增方法:imageWithRenderingMode:,它使用UIImageRenderingMode枚举值来设置图片的renderingMode属性。该枚举中包含下列值:12345678// 根据图片的使用环境和所处的绘图上下文自动调整渲染模式UIImageRenderingModeAutomatic // 始终绘制图片原始状态,不使用Tint ColorUIImageRenderingModeAlwaysOriginal // 始终根据Tint Color绘制图片,忽略图片的颜色信息UIImageRenderingModeAlwaysTemplaterenderingMode属性的默认值是UIImageRenderingModeAutomatic,即UIImage是否使用Tint Color取决于它显示的位置。其余状况能够看下面的图例:
如下的代码说明了使用一个既定的rendering模式建立图片是多么简单:123UIImage *img = [UIImage imageNamed:@"myimage"]; img = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];8、tintcolor VS barTintColoriOS7中你可使用一个给定的颜色,甚至是记入颜色主题来给整个app着色,帮助你的app脱颖而出。设置app的tint color很简答,只要使用UIView的新属性tintColor便可。这个属性是否听上去很熟悉呢?应该很熟悉,有些类,好比说UINaviagtionBar,UISearchBar,UITabBar以及UIToolbar已经有了这么命名的属性。他们如今有了一个新的属性:barTintColor。为了不使用新属性的时候犯错误,若是你的appp须要支持iOS6之前的系统的时候,请检查一下。12345678UINavigationBar *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当中被删除了:12345+ (UIColor *)viewFlipsideBackgroundColor; + (UIColor *)scrollViewTexturedBackgroundColor; + (UIColor *)underPageBackgroundColor;
10、UIButtonTypeRoundRect被UIButtonTypeSystem取代了4673_140117110855_1
在iOS开发刚开始就陪伴着你的老朋友如今也被删除了,它就是UIButtonTypeRoundRect ,被新的UIButtonTypeSystem取代了。若是每次iOS系统的发布都没有一些新的功能会是什么样子?这些新功能相信大部分开发者已经知道了,你可能会发现一些新颖的方式将它们整合到你的app中去!
11、检查无线路由是否可用定制一个视频播放器的能力在iOS版本每次的发布中一直有所进步。好比说,在iOS6以前,你不能在MPVolumeView中改变AirPlay的icon。在iOS7当中,你能够经过AirPlay,蓝牙或是其余的虚线机制了解是否有一个远程的设备可用。了解它的话,就可让你的app在恰当的时候作恰当的事,好比说,在没有远程设备的时候就不显示AirPlay的icon。如下是新增长到MPVolumeView的新属性和推送1234
@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中如何使用这个新功能:123456789101112131415161718192021222324@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。
十3、经过iCloud同步用户设备的密码iOS7以及Mavericks增长了iCloud Keychain来提供密码,以及iCloud中一些敏感数据的同步。开发者能够经过keychain中的kSecAttrSynchronizable key来遍历dictionary对象。因为直接处理keychain比较难,封装库提供了一个简单的处理keychain的方法。SSKeychain封装库多是最有名的的一个,做为一种福利,如今它支持在iCloud同步。如下代码片断显示了如何使用SSKeychain:
#import
- (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的好方法。
十4、使用NSAttributedString显示HTML在app中使用webview有时会让人很是沮丧,即便只是显示少许的HTMLneirong ,webview也会消耗大量的内存。如今iOS7让这些变得简单了,你能够从用少许代码在HTML文件中建立一个NSAttributedString,好比:1234NSString *html = @"Wow!NowiOScan create
NSAttributedString
from HTMLs!";NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}; NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUTF8StringEncoding] options:options documentAttributes:nil error:nil];如今你能够在任意的UIKit对象上使用NSAttributedString 了,好比说是一个UILabel或是一个UITextField。注意:NSHTMLTextDocumentType 只是NSDocumentTypeDocumentAttribute key一种可能的值。你还可使用NSPlainTextDocumentType,NSRTFTextDocumentType或是NSRTFDTextDocumentType。你还能够从NSAttributedString中建立一个HTML字符串,以下:12345NSAttributedString *attrString;
// from previous codeNSDictionary *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了。
十5、使用原生的Base64Base64是使用ASCII码显示二进制数据的一种流行方法。直到如今,开发者还不得不使用开源的工具来编码解码Base64的内容。如今iOS7引入了如下四种新的NSData方法来操做Base64编码的数据:12345678// From NSData.h- (id)initWithBase64EncodedString:(NSString *)base64String options:(NSDataBase64DecodingOptions)options; - (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options; - (id)initWithBase64EncodedData:(NSData *)base64Data options:(NSDataBase64DecodingOptions)options;
- (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options;这些方法能够帮助你轻易的将NSData对象转化为Base64,或者将Base64转化为NSData object。见如下的例子:1234567NSData* 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或者更早之前的系统,你可使用如下两个方法:123456/* 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 theNSDataBase64Encodingcategory. However, these methods have existed for several releases, so they may be used for applications targeting releases prior to OS X 10.9 and iOS 7.0. */- (id)initWithBase64Encoding:(NSString *)base64String;- (NSString *)base64Encoding;
十6、使用UIApplicationUserDidTakeScreenshotNotification来检查截图在iOS7以前,像Snapshot或是Facebook Poke这样的app是使用一些很精巧的方法来检测用户是否有截图
。然而,iOS7提供一个崭新的推送方法:UIApplicationUserDidTakeScreenshotNotification。只要像往常同样订阅便可知道何时截图了。注意:UIApplicationUserDidTakeScreenshotNotification 将会在截图完成以后显示。如今在截图截取以前没法获得通知。但愿苹果会在iOS8当中增长UIApplicationUserWillTakeScreenshotNotification。
十7、实现多语言语音合成若是可让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];
十8、使用了新的UIScreenEdgePanGestureRecognizerUIScreenEdgePanGestureRecognizer 继承自UIPanGestureRecognizer ,它可让你从屏幕边界便可检测手势。使用新的手势识别器很简单,见如下:UIScreenEdgePanGestureRecognizer *recognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleScreenEdgeRecognizer:)];recognizer.edges = UIRectEdgeLeft;[self.view addGestureRecognizer:recognizer];
十9、使用UIScrollViewKeyboardDismissMode实现了Message app的行为像Messages app同样在滚动的时候可让键盘消失是一种很是好的体验。然而,将这种行为整合到你的app很难。幸运的是,苹果给UIScrollView添加了一个很好用的属性keyboardDismissMode,这样能够方便不少。如今仅仅只须要在Storyboard中改变一个简单的属性,或者增长一行代码,你的app能够和办到和Messages app同样的事情了。这个属性使用了新的UIScrollViewKeyboardDismissMode enum枚举类型。
这个enum枚举类型可能的值以下:UIScrollViewKeyboardDismissModeNone // the keyboard is not dismissed automatically when scrollingUIScrollViewKeyboardDismissModeOnDrag
// dismisses the keyboard when a drag beginsUIScrollViewKeyboardDismissModeInteractive
// the keyboard follows the dragging touch off screen, and may bepulled upward again to cancel the dismiss如下是让键盘能够在滚动的时候消失须要设置的属性:
二10、使用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!");
}}
二11、给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 linkstextView.attributedText = attributedString;textView.delegate = self;这样就可让连接在文本中显示。然而,你也能够控制当连接被点击的时候会发生什么,实现这个可使用UITextViewDelegate协议的新的shouldInteractWithURL方法,就像这样:123456789- (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}iOS8新特性1、UIAlertController对alert&actionSheet的封装UIAlertController.h提示框按钮的选择123456789typedef NS_ENUM(NSInteger, UIAlertActionStyle) { UIAlertActionStyleDefault = 0, UIAlertActionStyleCancel, UIAlertActionStyleDestructive } NS_ENUM_AVAILABLE_IOS(8_0);提示框的样式123456789typedef NS_ENUM(NSInteger, UIAlertControllerStyle) { UIAlertControllerStyleActionSheet = 0, UIAlertControllerStyleAlert } NS_ENUM_AVAILABLE_IOS(8_0); NS_CLASS_AVAILABLE_IOS(8_0)
@interface UIAlertAction : NSObject建立提示框按钮1234567891011
+ (instancetype)actionWithTitle:(NSString *)title style:(UIAlertActionStyle)style handler:(void (^)(UIAlertAction *action))handler; @property (nonatomic, readonly) NSString *title;
@property (nonatomic, readonly) UIAlertActionStyle style; @property (nonatomic, getter=isEnabled) BOOL enabled; @end NS_CLASS_AVAILABLE_IOS(8_0)
@interface UIAlertController : UIViewController建立提示框1
+ (instancetype)alertControllerWithTitle:(NSString *)title message:(NSString *)message preferredStyle:(UIAlertControllerStyle)preferredStyle;添加按钮123
- (void)addAction:(UIAlertAction *)action;
@property (nonatomic, readonly) NSArray *actions;添加文本输入框123456789
- (void)addTextFieldWithConfigurationHandler:(void (^)(UITextField *textField))configurationHandler;
@property (nonatomic, readonly) NSArray *textFields; @property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *message; @property (nonatomic, readonly) UIAlertControllerStyle preferredStyle;简单实用示例:1234567891011
// 1.建立提示框对象,默认是actionSheet效果UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"注意" message:@"个人呈现方式变了" preferredStyle:UIAlertControllerStyleAlert];
// 2.建立取消按钮并添加到提示框上[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { NSLog(@"取消按钮被点击了");}]];
// 3.呈现提示框[self presentViewController:alert animated:YES completion:nil];
2、UIPopoverController直接经过present方式呈现UIViewController.h1234567891011121314151617181920212223typedef NS_ENUM(NSInteger, UIModalPresentationStyle)
{
UIModalPresentationFullScreen = 0, UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2), UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2), UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2), UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0), UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0), UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0), UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0), UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1, }; @property (nonatomic,readonly) UIPopoverPresentationController *popoverPresentationController NS_AVAILABLE_IOS(8_0);使用示例:1234567891011// 1.建立内容控制器UITableViewController *contentVc = [[UITableViewController alloc] init];
// 2.1 设置呈现方式
contentVc.modalPresentationStyle = UIModalPresentationPopover;
// 2.2设置在导航栏的左边按钮呈现contentVc.popoverPresentationController.barButtonItem = self.navigationItem.leftBarButtonItem;
// 3.呈现[self presentViewController:contentVc animated:YES completion:nil];之前的方式:12345678910
// 1.建立内容控制器UITableViewController *contentVc = [[UITableViewController alloc] init];
// 2.建立popoverUIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:contentVc]; popover.popoverContentSize = CGSizeMake(100, 100);
// 3.呈现[popover presentPopoverFromBarButtonItem:self.navigationItem.leftBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
3、获取用户受权的用户隐私保护地图定位示例 :1234567891011121314151617181920212223242526// 导入定位框架#import@interface ViewController ()// 设置定位对象
@property(nonatomic,strong)CLLocationManager* maneger;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 当使用iOS8定位的时候须要请求用户受权,且在info.plist里添加字段NSLocationAlwaysUsageDescription 请求用户受权的描述
// iOS7仅仅须要在info.plist里添加字段Privacy - Location Usage Description 请求用户受权的描述
// 不须要再写下面的代码
if (IOS8) {
[self.maneger requestAlwaysAuthorization];//请求用户受权
}
// 开启定位
[self.maneger startUpdatingLocation];
}
4、针对屏幕适配应运而生的size classes
size classes是为了解决storyboard只能订制一种屏幕样式的问题,它再也不是具体的尺寸,而是抽象尺寸经过宽/高 的compact、any、regular 组成了九种组合包含了全部苹果设备的尺寸。
iOS9新特性
1、网络适配
iOS9系统发送的网络请求将统一使用TLS 1.2 SSL。采用TLS 1.2 协议,目的是强制加强数据访问安全,并且系统Foundation框架下的相关网络请求,将再也不默认使用HTTP等不安全的网络协议,而默认采用TLS 1.2。服务器所以须要更新,以解析相关数据。如不更新,可经过在 info.plist 中声明,倒退回不安全的网络请求。
什么是SSL/TLS?跟HTTP和HTTPS有什么关系?
跟往常同样,先说结论:
1
HTTP + SSL/TLS + TCP = HTTPS
TLS 是 SSL 新的别称。举个例子:
“TLS1.0”之于“SSL3.1”,犹“公元2015”之于“民国104”,或者是“一千克”之于“一公斤”,或者是“半斤”之于“八两”:称呼不一样,但意思相同。
SSL 3.0版本以后的迭代版本被从新命名为TLS 1.0,也就是说:
1 TLS 1.0 = SSL 3.1
因此他们是一个东西,咱们日常也常常简单见到 “SSL/TLS” 这种说法。经常使用的是下面这些:
1 SSL 2.0
2 SSL 3.0
3 TLS 1.0 (SSL 3.1)
4 TLS 1.1 (SSL 3.1)
5 TLS 1.2 (SSL 3.1)
那为何标题是“使用HTTPS”而没有说起SSL和TLS什么事? 要理解这个,要看下一个公式:
1
HTTP + SSL/TLS + TCP = HTTPS
打个比方:若是原来的 HTTP 是塑料水管,容易被戳破;那么现在新设计的 HTTPS 就像是在原有的塑料水管以外,再包一层金属水管。一来,原有的塑料水管照样运行;二来,用金属加固了以后,不容易被戳破。
目前,应用最普遍的是TLS 1.0,接下来是SSL 3.0。可是,主流浏览器都已经实现了TLS 1.2的支持。Apple让你的HTTP采用SSL/TLS协议,就是让你从HTTP转到HTTPS。
之前的HTTP不是也能用吗?为何要用SSL/TLS,闲得慌?!Apple是否是又在反人类?
不使用SSL/TLS的HTTP通讯,就是不加密的通讯!
全部信息明文传播,带来了三大风险:
窃听风险(eavesdropping):第三方能够获知通讯内容。
篡改风险(tampering):第三方能够修改通讯内容。
冒充风险(pretending):第三方能够冒充他人身份参与通讯。
SSL/TLS协议是为了解决这三大风险而设计的,但愿达到:
全部信息都是加密传播,第三方没法窃听。
具备校验机制,一旦被篡改,通讯双方会马上发现。
配备身份证书,防止身份被冒充。
如何适配?---弱弱地问下:加班要多久?
正如文章开头所说:
TLS 1.2 协议 强制加强数据访问安全 系统 Foundation 框架下的相关网络请求,将再也不默认使用 HTTP 等不安全的网络协议,而默认采用 TLS 1.2。服务器所以须要更新,以解析相关数据。如不更新,可经过在 Info.plist 中声明,倒退回不安全的网络请求。
方案一:当即让公司的服务端升级使用TLS 1.2。
方案二:虽Apple不建议,但可经过在 Info.plist 中声明,倒退回不安全的网络请求依然能让App访问指定http,甚至任意的http。
上面是比较严谨的作法,指定了能访问哪些特定的HTTP。固然也有暴力的作法: 完全倒退回不安全的HTTP网络请求,能任意进行HTTP请求,好比你在开发一款浏览器App,或者你想偷懒,或者后台想偷懒,或者公司不给你升级服务器。但目前Apple的官方文档并未说起如何在 info.plist 配置能够参考本文:http://blog.6ag.cn/1065.html
2、更灵活的后台定位
若是不适配iOS9,就不能偷偷在后台定位。不过苹果将容许出现这种场景:
同一App中的多个location manager,一些只能在前台定位,另外一些可在后台定位,并可随时开启或者关闭特定location manager的后台定位。
如何偷偷在后台定位:
// 1. 实例化定位管理器
_locationManager = [[CLLocationManager alloc] init];
// 2. 设置代理
_locationManager.delegate = self;
// 3. 定位精度
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
// 4.请求用户权限:分为:?只在前台开启定位?在后台也可定位,
//注意:建议只请求?和?中的一个,若是两个权限都须要,只请求?便可,
//??这样的顺序,将致使bug:第一次启动程序后,系统将只请求?的权限,?的权限系统不会请求,只会在下一次启动应用时请求?
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {
//[_locationManager requestWhenInUseAuthorization];//?只在前台开启定位
[_locationManager requestAlwaysAuthorization];//?在后台也可定位
}
// 5.iOS9新特性:将容许出现这种场景:同一app中多个location manager:一些只能在前台定位,另外一些可在后台定位(并可随时禁止其后台定位)。
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
_locationManager.allowsBackgroundLocationUpdates = YES;
}
// 6. 更新用户位置
[_locationManager startUpdatingLocation];
可是若是照着这种方式尝试,而没有配置info.plist,100%你的程序会崩溃掉,并报错:
*** Assertion failure in -[CLLocationManager setAllowsBackgroundLocationUpdates:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/CoreLocationFramework_Sim/CoreLocation-1808.1.5/Framework/CoreLocation/CLLocationManager.m:593
要将 info.plist 配置以下:
对应的 Info.plist 的XML源码是:
3、Bitcode
bitcode的理解应该是把程序编译成的一种过渡代码,而后苹果再把这个过渡代码编译成可执行的程序。bitcode也容许苹果在后期从新优化咱们程序的二进制文件,有相似于App瘦身的思想。将来Watch应用须包含Bitcode,iOS不强制,但Xcode7默认会开启Bitcode。
用了xcode7的编译器编译以前没问题的项目可能会出现下列报错。
XXXX’ does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode forthistarget. forarchitecture arm64
问题的缘由是:某些第三方库还不支持bitcode。要否则是等待库的开发者升级了此项功能咱们更新库,要不就是把这个bitcode禁用。禁用Bitcode,方法见下图:
4、企业级分发
iOS9以前,企业级分发十分方便:点击App出现“信任按钮”。
iOS9之后,企业级分发ipa包将遭到与Mac上dmg安装包同样的待遇。默认不能安装,也再也不出现“信任按钮”,必须让用户进行gif图中的设置。
5、URL scheme
URL scheme通常使用的场景是应用程序有分享或跳其余平台受权的功能,分享或受权后再跳回来。在iOS8并无作过多限制,在iOS9中,若是使用URL scheme必须在"info.plist"中将你要在外部调用的URL scheme列为白名单,不然不能使用。
canOpenURL: failed forURL : "mqzone://qqapp"- error: "This app is not allowed to query for scheme mqzone"
具体的解决方案也是要在info.plist中设置 LSApplicationQueriesSchemes 类型为数组,下面添加全部你用到的scheme
推荐一篇博客: http://awkwardhare.com/post/121196006730/quick-take-on-ios-9-url-scheme-changes
其中最关键的是如下部分:
If you call the “canOpenURL” method on a URL that is not in your whitelist, it will return “NO”, even if there is an app installed that has registered to handle this scheme. A “This app is not allowed to query for scheme xxx” syslog entry will appear.
If you call the “openURL” method on a URL that is not in your whitelist, it will fail silently. A “This app is not allowed to query for scheme xxx” syslog entry will appear.
6、新字体
iOS8中,字体是Helvetica,中文的字体有点相似于“华文细黑”。只是苹果手机自带渲染,因此看上去可能比普通的华文细黑要美观。iOS9中,中文系统字体变为了专为中国设计的“苹方” 有点相似于一种word字体“幼圆”。字体有轻微的加粗效果,而且最关键的是字体间隙变大了!
因此不少本来写死了width的label可能会出现“...”的状况。
上面这两张图也能够直观的看出同一个界面,同一个label的变化。
因此为了在界面显示上不出错,就算是固定长度的文字也仍是建议使用sizetofit 或者ios向上取整 ceilf() 或者提早计算。
1 CGSize size = [title sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14.0f]}];
2 CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));
7、tableview
虽然如今的iOS9已经推送正式版了,可是iOS9使用时仍是会感受到App比之前更加卡顿了,tableView拖动时卡顿显示的最为明显。 而且以前遇到一个bug,本来好的项目用xcode7一编译,tableView刷新出了问题 ,[tableView reloadData]无效,有一行cell明明改变了可是刷新不出来。 感受多是这个方法和某种新加的特性冲突了,猜想多是reloadData的操做被推迟到下一个RunLoop执行最终失效。
解决的方法是,注释[tableView reloadData],改用局部刷新,问题竟然就解决了。
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
8、iPad适配Slide Over 和 Split View
iPad适配Slide Over 和 Split View,若想适配multi tasking特性,惟一的建议:
弃纯代码,改用storyboard、xib,纵观苹果WWDC全部Demo均是如此。
1 Mysteries of Auto Layout, Part 1
2 What's New in Storyboards
3 Implementing UI Designs in Interface Builder
4 Getting Started with Multitasking on iPad in iOS 9
5 Optimizing Your App for Multitasking on iPad in iOS