對(duì)iOS13 適配的總結(jié)帅刊,下面有些是自己遇到的,有些是收集的漂问,希望能給大家一些思路
-
iOS13中presentViewController的問題
-
iOS不允許valueForKey赖瞒、setValue: forKey獲取和設(shè)置私有屬性,需要使用其它方式修改
-
黑線處理crash
-
黑夜模式 審核強(qiáng)制要求適配黑夜模式蚤假。
-
iOS13上獲取DeviceToken
-
App啟動(dòng)過程中栏饮,部分View可能無(wú)法實(shí)時(shí)獲取到frame
-
狀態(tài)欄(StatusBar)
-
Sign in with Apple -提供第三方登錄
-
即將廢棄的 LaunchImage
-
MPMoviePlayerController 在iOS 13已經(jīng)不能用了
-
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
-
UISegmentedControl 選中的顏色
-
內(nèi)嵌WebView,一些圖片路徑磷仰,文件路徑袍嬉,不用寫絕對(duì)路徑,直接寫文件名字即可芒划,
-
獲取網(wǎng)絡(luò)狀態(tài)用到KVC的那種方法會(huì)發(fā)生崩潰
- 在iOS13中運(yùn)行代碼發(fā)現(xiàn)presentViewController和之前彈出的樣式不一樣冬竟。
會(huì)出現(xiàn)這種情況是主要是因?yàn)槲覀冎皩?duì)UIViewController里面的一個(gè)屬性欧穴,即modalPresentationStyle(該屬性是控制器在模態(tài)視圖時(shí)將要使用的樣式)沒有設(shè)置需要的類型。在iOS13中modalPresentationStyle的默認(rèn)改為UIModalPresentationAutomatic,而在之前默認(rèn)是UIModalPresentationFullScreen泵殴。
ViewController *vc = [[ViewController alloc] init];
vc.title = @"presentVC";
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
nav.modalPresentationStyle = UIModalPresentationFullScreen;
[self.window.rootViewController presentViewController:nav animated:YES completion:nil];
注意:如果你某個(gè)控制器想使用卡片模式涮帘,需要注意你這個(gè)控制器底部是否有控件⌒ψ纾卡片式的底部的控件容易被遮擋调缨。比方說TZPhotoPickerController 這個(gè)常用的開源相冊(cè)控件。當(dāng)選擇照片時(shí)底部的確定按鈕就被遮擋吆你。無(wú)法選中
- 在使用iOS 13運(yùn)行項(xiàng)目時(shí)突然APP就crash掉了弦叶。定位到的問題是在設(shè)置UITextField的Placeholder也就是占位文本的顏色和字體時(shí)使用了KVC的方法:
[_textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
[_textField setValue:[UIFont systemFontOfSize:14] forKeyPath:@"_placeholderLabel.font"];
可將其替換為
_textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"姓名" attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14],NSForegroundColorAttributeName:[UIColor redColor]}];
UIsearchBar 使用“ _searchField”崩潰修改方式
UITextField *searchField;
if (@available(iOS 13.0, *)) {
searchField =[self.searchBar valueForKey:@"_searchTextField"];
}else
{
searchField = [ self.searchBar valueForKey:@"_searchField"];
}
- 之前為了處理搜索框的黑線問題會(huì)遍歷后刪除UISearchBarBackground,在iOS13會(huì)導(dǎo)致UI渲染失敗crash;解決辦法是設(shè)置UISearchBarBackground的layer.contents為nil
public func clearBlackLine() {
for view in self.subviews.last!.subviews {
if view.isKind(of: NSClassFromString("UISearchBarBackground")!) {
view.backgroundColor = UIColor.white
view.layer.contents = nil
break
}
}
}
- 審核強(qiáng)制要求適配黑夜模式妇多。
// 模式強(qiáng)制切換
if (darkMode) {
if (@available(iOS 13.0, *)) {
[UIApplication sharedApplication].keyWindow.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
}
} else {
if (@available(iOS 13.0, *)) {
[UIApplication sharedApplication].keyWindow.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
}
在 Info.plist 文件中伤哺,添加 key 為 User Interface Style,類型為 String者祖,value 設(shè)置為 Light 可關(guān)閉黑暗模式立莉。
已知問題
- YYLabel 如果使用了 textLayout屬性,切換模式的時(shí)候 無(wú)法自動(dòng)修改layout文本的顏色
- 內(nèi)嵌WebView七问,需要手動(dòng)修改css樣式
- iOS13 正確的獲得Devicetoken的代碼如下:
#include <arpa/inet.h>
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
if (![deviceToken isKindOfClass:[NSData class]]) return;
const unsigned *tokenBytes = (const unsigned *)[deviceToken bytes];
NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
NSLog(@"deviceToken:%@",hexToken);
}
https://developer.umeng.com/docs/66632/detail/126489
- 可能是為了優(yōu)化啟動(dòng)速度蜓耻,App 啟動(dòng)過程中,部分View可能無(wú)法實(shí)時(shí)獲取到正確的frame
- 狀態(tài)欄(StatusBar)
目前狀態(tài)欄也增加了一種模式械巡,由之前的兩種刹淌,變成了三種, 其中default由之前的黑色內(nèi)容,變成了會(huì)根據(jù)系統(tǒng)模式讥耗,自動(dòng)選擇當(dāng)前展示lightContent還是darkContent有勾。
public enum UIStatusBarStyle : Int {
case `default` // Automatically chooses light or dark content based on the user interface style
@available(iOS 7.0, *)
case lightContent // Light content, for use on dark backgrounds
@available(iOS 13.0, *)
case darkContent // Dark content, for use on light backgrounds
}
我們?cè)谑褂玫臅r(shí)候,就可以重寫preferredStatusBarStyle的get方法:
override var preferredStatusBarStyle: UIStatusBarStyle{
get{
return .lightContent
}
}
- Sign in with Apple -提供第三方登錄的注意啦
如果你的應(yīng)用使用了第三方登錄葛账,那么你可能也需要加下 「Sign in with Apple」
Sign In with Apple will be available for beta testing this summer. It will be required as an option for users in apps that support third-party sign-in when it is commercially available later this year.
- 即將廢棄的 LaunchImage
從 iOS 8 的時(shí)候柠衅,蘋果就引入了 LaunchScreen皮仁,我們可以設(shè)置 LaunchScreen來(lái)作為啟動(dòng)頁(yè)籍琳。當(dāng)然,現(xiàn)在你還可以使用LaunchImage來(lái)設(shè)置啟動(dòng)圖贷祈。不過使用LaunchImage的話趋急,要求我們必須提供各種屏幕尺寸的啟動(dòng)圖,來(lái)適配各種設(shè)備势誊,隨著蘋果設(shè)備尺寸越來(lái)越多呜达,這種方式顯然不夠 Flexible。而使用 LaunchScreen的話粟耻,情況會(huì)變的很簡(jiǎn)單查近, LaunchScreen是支持AutoLayout+SizeClass的眉踱,所以適配各種屏幕都不在話下。
注意啦??霜威,從2020年4月開始谈喳,所有使? iOS13 SDK的 App將必須提供 LaunchScreen,LaunchImage即將退出歷史舞臺(tái)戈泼。
- MPMoviePlayerController 在iOS 13已經(jīng)不能用了
10.UISegmentedControl 選中的顏色
if ( @available(iOS 13.0, *)) {
self.segmentedControl.selectedSegmentTintColor = [UIColor clearColor];
}else
{
self.segmentedControl.tintColor = [UIColor clearColor];
}
- 內(nèi)嵌WebView婿禽,一些圖片路徑,文件路徑大猛,不用寫絕對(duì)路徑扭倾,直接寫文件名字即可
http://www.reibang.com/p/767e6f2d8435
12.下面這種獲取網(wǎng)絡(luò)狀態(tài)的方法會(huì)發(fā)生崩潰
UIApplication *app = [UIApplication sharedApplication];
NSArray *children = nil;
// 不能用 [[self deviceVersion] isEqualToString:@"iPhone X"] 來(lái)判斷,因?yàn)槟M器不會(huì)返回 iPhone X
id statusBar = [app valueForKeyPath:@"statusBar"];
if ([statusBar isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
children = [[[statusBar valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
} else {
children = [[statusBar valueForKey:@"foregroundView"] subviews];
}
NSString *state = [[NSString alloc] init];
int netType = 0;
for (id child in children) {
if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
//獲取到狀態(tài)欄
netType = [[child valueForKeyPath:@"dataNetworkType"] intValue];
switch (netType) {
case 0:
state = @"none";
break;
case 1:
state = @"2G";
break;
case 2:
state = @"3G";
break;
case 3:
state = @"4G";
break;
case 5:
state = @"WIFI";
break;
default:
break;
}
}
}