http://blog.csdn.net/phunxm/article/details/42174937
一、IOS8適配遇到的問(wèn)題
1、不能定位
打勾 設(shè)置- 隱私-定位服務(wù)-你的app-使用應(yīng)用程序期間(始終)
打開(kāi)app再進(jìn)設(shè)置后會(huì)發(fā)現(xiàn),你打勾的使用程序期間(始終)又給取消了
原來(lái)iOS8需要一些方法。
如果需要僅在前臺(tái)定位,你在調(diào)用startUpdatingLocation 前需要調(diào)用requestWhenInUseAuthorization
如果需要在前后臺(tái)定位,你在調(diào)用startUpdatingLocation 前需要調(diào)用requestAlwaysAuthorization
同 時(shí)在plist文件中添加NSLocationWhenInUseUsageDescription或NSLocationAlwaysUsageDescription字段,值寫(xiě)"需要定位"就可以了,也可以是其他的,這個(gè)提示文字"需要定位"在詢問(wèn)用戶授權(quán)的時(shí)候會(huì)顯示到的。
1.if ([[[UIDevice currentDevice] systemVersion] floatValue]>= 8.0) {
2.[_locationManager requestWhenInUseAuthorization];
3.}
4.
5.[_locationManager startUpdatingLocation];
2、推送不管用
01.if ([[[UIDevice currentDevice] systemVersion] floatValue]>= 8.0) {
02.[app registerForRemoteNotifications];
03.
04.UIUserNotificationSettings *settings =[UIUserNotificationSettings settingsForTypes:
05.UIRemoteNotificationTypeAlert
06.| UIRemoteNotificationTypeBadge
07.| UIRemoteNotificationTypeSoundcategories:nil];
08.[appregisterUserNotificationSettings:settings];
09.
10.} else {
11.[app registerForRemoteNotificationTypes:
12.UIRemoteNotificationTypeAlert
13.| UIRemoteNotificationTypeBadge
14.| UIRemoteNotificationTypeSound];
15.}
ios8注冊(cè)推送分兩步走,
1》注冊(cè)用戶通知
UIUserNotificationSettings *settings =[UIUserNotificationSettings settingsForTypes:
UIRemoteNotificationTypeAlert
| UIRemoteNotificationTypeBadge
| UIRemoteNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
2》用戶通知注冊(cè)成功后,會(huì)走如下回調(diào),在回調(diào)函數(shù)中進(jìn)行推送注冊(cè):
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
- (void)application:(UIApplication *)applicationdidRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings
{
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
#endif
3》接下來(lái)就走以前的推送回調(diào):
- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken? //成功回調(diào)
- (void)application:(UIApplication*)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError*)error??????? //失敗回調(diào)
判斷推送打開(kāi)開(kāi)關(guān),ios8以前的代碼:
[[UIApplication sharedApplication]enabledRemoteNotificationTypes]!=UIRemoteNotificationTypeNone;
ios8需要換成如下代碼:
[[UIApplication sharedApplication]isRegisteredForRemoteNotifications]
3、某些系統(tǒng)控件的布局計(jì)算延遲到繪制時(shí)才發(fā)生:
舉個(gè)例子:
UIButton * button = [UIButtonbuttonWithType:UIButtonTypeCustom];
[buttonsetTag:i];
[buttonsetTitle:siteData.info.title
forState:UIControlStateNormal];
[button.titleLabel setLineBreakMode:NSLineBreakByTruncatingTail];
[buttonsetTitleColor:[UIColor colorWithHexValue:0x000000]
forState:UIControlStateNormal];
[buttonsetTitleColor:[UIColor colorWithHexValue:0xffffff]
forState:UIControlStateHighlighted];
[buttonsetTitleColor:[UIColor colorWithHexValue:0xffffff]
forState:UIControlStateSelected];
[button.titleLabel setFont:[UIFont systemFontOfSize:14]];
[button setBackgroundColor:[UIColorclearColor]];
UIImage*image = [UIImage imageNamed:@"sourceSelect"];
image =[image resizableImageWithCapInsets:UIEdgeInsetsMake(4, 2, 4, 2)];
[buttonsetBackgroundImage:nil
forState:UIControlStateNormal];
[buttonsetBackgroundImage:image
forState:UIControlStateHighlighted];
[buttonsetBackgroundImage:image
forState:UIControlStateSelected];
button.exclusiveTouch = YES;
button.selected = NO;
UIImage*tmpImg = [Utility ImageFromColor:[UIColor clearColor]
rect:CGRectMake(0, 0, 47, 60)];
[buttonsetImageWithURL:[NSURL URLWithString:siteData.info.logoURL]
placeholderImage:tmpImg];
//ios8layout會(huì)延遲到渲染的時(shí)候,這個(gè)地方需要算坐標(biāo),所以需要手動(dòng)強(qiáng)制layout
[buttonsetNeedsLayout];
[button layoutIfNeeded];
NSIntegertitleWidth = CGRectGetWidth(button.titleLabel.frame);
4、某些系統(tǒng)控件的動(dòng)畫(huà)會(huì)有延遲現(xiàn)象:
例子:
[UIViewbeginAnimations:nil context:nil];
[UIViewsetAnimationDuration:duration];
[progressBar setAlpha:alpha];
progressBar.frame = frame;
[UIView commitAnimations];
以上代碼是瀏覽器進(jìn)度條變化的動(dòng)畫(huà),在IOS7工作良好,在Ios8中卻會(huì)出現(xiàn)進(jìn)度后退的奇怪現(xiàn)象。
5、UITableViewCell有一個(gè)默認(rèn)size(320,44):
在- (id)initWithStyle:(UITableViewCellStyle)stylereuseIdentifier:(NSString *)reuseIdentifier方法中不要依賴于self.frame或者self.contentView.frame,因?yàn)檫@個(gè)時(shí)候的size都是默認(rèn)值size(320,44).
有兩種解決方法,
1>>重寫(xiě)setFrame方法,
-(void)setFrame:(CGRect)frame
{
frame.size.width=VIEW_WIDTH;//VIEW_WIDTH這里是屏幕豎屏?xí)r的寬
[supersetFrame:frame];
}
2>>在- (id)initWithStyle:(UITableViewCellStyle)stylereuseIdentifier:(NSString *)reuseIdentifier方法中把寬寫(xiě)死,不要寫(xiě)成根據(jù)self.frame.width算出來(lái)的值,例如需要與屏幕等寬,用[UIScreen mainScreen].bounds.width,
二、Iphone6&6p適配遇到的問(wèn)題
1、如何管理圖片,對(duì)于6p圖片加上@3x后綴,系統(tǒng)即可自動(dòng)為我們加載所需要的圖片,但是對(duì)于6的話,由于6和4/4s/5/5s的倍率是一樣的,如果想針對(duì)6單獨(dú)做圖片的話,系統(tǒng)就無(wú)法知道我們要加載的圖片是哪一個(gè)了。這個(gè)時(shí)候有兩種做法:
1》》做一個(gè)人為約定,例如針對(duì)6的圖片名字都加上“_6”后綴,然后針對(duì)UIImage做個(gè)擴(kuò)展:
例如:
+(instancetype)imageNamedForDevices:(NSString*)imageName
{
NSRangeatPos=[imageName rangeOfString:@"@"];
if(atPos.location!=NSNotFound) {
imageName=[imageName substringToIndex:atPos.location];
}
UIImage* defaultImage=[UIImage imageNamed:imageName];
UIImage* iphone6Image=defaultImage;
if(![imageName hasSuffix:@"_6"])
{
iphone6Image=[UIImage imageNamed:[imageName stringByAppendingString:@"_6"]];
if(!iphone6Image) {
iphone6Image=defaultImage;
}
}
returnVALUE_FOR_UNIVERSE_DEVICE(defaultImage, iphone6Image, defaultImage);
}
這樣的話,加入我們有個(gè)圖片有針對(duì)5s,6,6p有三個(gè)版本,分別命名為home_bar@2x.png, home_bar_6@2x.png, home_bar@3x.png,
我們?cè)诔绦蛑兄灰{(diào)用[UIImage imageNamedForDevices:@”home_bar”];就可以根據(jù)設(shè)備獲取到對(duì)應(yīng)版本的圖片。
2》》手動(dòng)寫(xiě)if else語(yǔ)句,根據(jù)設(shè)備編寫(xiě)不同的獲取圖片的代碼,不推薦這種做法。
2、如何針對(duì)特定設(shè)備做定制化需求:
typedef enum
{
iPhoneDeviceTypeIPhone4,
iPhoneDeviceTypeIPhone4S=iPhoneDeviceTypeIPhone4,
iPhoneDeviceTypeIPhone5,
iPhoneDeviceTypeIPhone5S=iPhoneDeviceTypeIPhone5,
iPhoneDeviceTypeIPhone6,
iPhoneDeviceTypeIPhone6P
}iPhoneDeviceType;
iPhoneDeviceType global_deviceType;
#define IS_IPHONE_5OR_ABOVE?? (global_deviceType>=iPhoneDeviceTypeIPhone5S)
#define IS_IPHONE_6P? (global_deviceType==iPhoneDeviceTypeIPhone6P)
#define IS_IPHONE_6OR_ABOVE??(global_deviceType>=iPhoneDeviceTypeIPhone6)
#define IS_IPHONE_6??????????(global_deviceType==iPhoneDeviceTypeIPhone6)
#define VALUE_FOR_UNIVERSE_DEVICE(a,b,c)((IS_IPHONE_6P)?(a):((IS_IPHONE_6)?(b):(c)))
//獲取設(shè)備尺寸信息
+(void)getDeviceType
{
iPhoneDeviceType type;
CGRectbounds=[[UIScreen mainScreen] bounds];
CGFloatheight=bounds.size.height;
CGFloatscale=[UIScreen mainScreen].scale;
if(height<568) {
type=iPhoneDeviceTypeIPhone4S;
}
elseif(height<667)
{
type=iPhoneDeviceTypeIPhone5S;
}
elseif(scale<2.9)
{
type=iPhoneDeviceTypeIPhone6;
}
else
{
type=iPhoneDeviceTypeIPhone6P;
}
global_deviceType=type;
}
VALUE_FOR_UNIVERSE_DEVICE這個(gè)宏能夠讓我們對(duì)設(shè)備的判斷集中到一點(diǎn),大大簡(jiǎn)化了代碼,a,b,c可以是任意類(lèi)型,只要保證a,b,c是同一類(lèi)型即可,a是為6P定制的值,b是為6定制的值,c是為6以下設(shè)別定制的值。
3、涉及到橫豎屏切換的VC,代碼凡是用到UIScreen、UIWindow定位的地方都需要改寫(xiě),把width換成MIN(width,height),把height換成MAX(height,width).
4、坐標(biāo)依賴法則:1>>ViewController中的所有坐標(biāo)應(yīng)該依賴于self.view.bounds;2>>UIView中的所有坐標(biāo)應(yīng)該依賴于self.bounds;3>>其他情況的坐標(biāo)應(yīng)該依賴于屏幕尺寸;1、2屬于相對(duì)坐標(biāo),3屬于絕對(duì)坐標(biāo)。我們應(yīng)該優(yōu)先考慮相對(duì)坐標(biāo),盡量少用絕對(duì)坐標(biāo)。
5、總體適配原則:1>>首先考慮橫向充滿,縱向根據(jù)需要增加高度;
2>>海報(bào)、大圖片、小窗播放器根絕橫向放大系數(shù)進(jìn)行等比放大;
3>>海報(bào)的內(nèi)邊距保持不變,海報(bào)與文字的距離保持不變,文字字體、文字上下之間的間距根據(jù)視覺(jué)需要做微調(diào);
4>>對(duì)于那些沒(méi)有專(zhuān)門(mén)提供iPhone6&6p切圖的圖片,為了保證圖片不虛,需要把frame寫(xiě)成與圖片尺寸一樣大。
6、關(guān)于適配解決方案的討論:
有三種方案:
1>>xib+autolayout;
這種方案是最為理想的適配方案,VC的坐標(biāo)體系一目了然,只需要簡(jiǎn)單計(jì)算即可適配新設(shè)備。前提是源代碼用到了xib來(lái)寫(xiě)VC.
2>>手寫(xiě)VC+手寫(xiě)autolayout;
個(gè)人認(rèn)為這種方案是最為繁瑣的方案,首先需要大量的坐標(biāo)計(jì)算,然后需要對(duì)VFL語(yǔ)法非常了解,解決約束依賴缺失或者沖突之類(lèi)的問(wèn)題,最后導(dǎo)致的結(jié)果是坐標(biāo)計(jì)算繁瑣復(fù)雜,代碼改動(dòng)非常大,代碼增加量很大,不易于維護(hù)。
3>>手寫(xiě)VC+手動(dòng)適配;
這種方案也避免不了繁瑣的坐標(biāo)計(jì)算,但是相對(duì)2方案來(lái)講,不需要去了解VFL語(yǔ)法,也不需要解決約束依賴缺失或者沖突之類(lèi)的問(wèn)題,代碼改動(dòng)量相對(duì)較少。我們工程中目前采用的就是這種方案。
原文鏈接:http://blog.csdn.net/xiao_quan/article/details/43038503