iOS13 適配問(wèn)題

1. 控制器的 modalPresentationStyle 默認(rèn)值變了

有用戶(hù)反映升級(jí) iOS13 后, 界面跳轉(zhuǎn)變成了小卡片...

查閱了下 UIModalPresentationStyle枚舉定義, 發(fā)現(xiàn)蘋(píng)果直接將modalPresentationStyle 默認(rèn)值改成這個(gè),有點(diǎn)不解;
默認(rèn)動(dòng)畫(huà) UIModalPresentationAutomatic;
如果想要恢復(fù)原來(lái)交互動(dòng)畫(huà)的話(huà),
需要設(shè)置一下modalPresentationStyle 屬性;

nav.modalPresentationStyle = UIModalPresentationFullScreen;

當(dāng)然,我們可以通過(guò)方法交換,來(lái)達(dá)到全局修改的目的:

@implementation UIViewController (ChangeModalStyle)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        swizzling_exchangeMethod([self class], @selector(presentViewController:animated:completion:), @selector(cx_presentViewController:animated:completion:));
    });
}

- (void)cx_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    //設(shè)置滿(mǎn)屏,不需要小卡片
    if(@available(iOS 13.0, *)) {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen;
    }
    [self cx_presentViewController:viewControllerToPresent animated:flag completion:completion];
}

2. KVC限制

iOS13不能通過(guò)KVC的方式隨意修改一些沒(méi)有暴露出來(lái)的屬性了.

比如常用的 TextField_placeholderLabel.textColorUISearchBar_searchField會(huì)報(bào)如下類(lèi)似的錯(cuò)誤;

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug'

還有statusBar

通過(guò)以下方式獲取statusBar的方式已經(jīng)不可取了,iOS13上繼續(xù)使用會(huì)造成crash。

UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];

報(bào)錯(cuò)信息如下:

reason: 'App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead.'

替代方式為UIWindowScenestatusBarManager對(duì)象;

3.iOS 13 推送 DeviceToken的變化

可能大多數(shù)使用第三方推送的童鞋都不會(huì)注意到這個(gè)問(wèn)題,一般現(xiàn)在的第三方推送都是將DeviceToken原始數(shù)據(jù)丟進(jìn)去,具體的解析都是第三方內(nèi)部處理,所以,這些第三方解析DeviceToken的方式正確的話(huà),那就毫無(wú)問(wèn)題。如果你們是通過(guò)這種方式來(lái)獲取DeviceToken,那你需要注意了:

NSString *dt = [deviceToken description];
dt = [dt stringByReplacingOccurrencesOfString: @"<" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @">" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @" " withString: @""];

解決辦法1:

NSMutableString *deviceTokenString = [NSMutableString string];
const char *bytes = deviceToken.bytes;
NSInteger count = deviceToken.length;
for (int i = 0; i < count; i++) {
    [deviceTokenString appendFormat:@"%02x", bytes[i]&0x000000FF];
}

或者你也可以使用極光提供的方法(2019年7月24日更新)

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    if (![deviceToken isKindOfClass:[NSData class]]) return;
    const unsigned *tokenBytes = [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);
}

4. CNCopyCurrentNetworkInfo變化

iOS13下不能正常獲取到WiFi的ssid,需要用戶(hù)開(kāi)啟定位權(quán)限或者使用新的API NEHotspotConfiguration獲取

5. MPMoviePlayerController 在iOS 13已經(jīng)不能用了

在使用到MPMoviePlayerController的地方,直接拋了異常

'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.' 

如何修改: 這個(gè)沒(méi)啥好說(shuō)的,既然不能再用了,那只能換掉了。替代方案就是AVKit里面的那套播放器。

6.黑暗模式

Apps on iOS 13 are expected to support dark mode Use system colors and materials Create your own dynamic colors and images Leverage flexible infrastructure

關(guān)于Dark Mode,這里補(bǔ)充幾點(diǎn)。

因?yàn)樘O(píng)果目前還沒(méi)有強(qiáng)制必須適配這個(gè),相信大家的很多項(xiàng)目也沒(méi)有開(kāi)始是配這個(gè)模式。所以,前期可以強(qiáng)制Light模式。不然,你可能會(huì)遇到一些問(wèn)題,比如UITableViewCell的背景色,如果你沒(méi)有設(shè)置過(guò)背景色的話(huà),它在Dark模式下就是黑色的,再比如UIDatePicker文字顏色等等。

那么怎么強(qiáng)制模式呢?

iOS 13給UIView和UIViewController都添加了一個(gè)屬性:

@property (nonatomic) UIUserInterfaceStyle overrideUserInterfaceStyle API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);

給這個(gè)屬性設(shè)置成某一種模式,即可強(qiáng)制顯示模式。
如果你想修改一處,應(yīng)用所有地方,那么你只需要設(shè)置widow的顯示模式即可,這會(huì)影響widow下面的所有視圖顯示模式,這也可以看出顯示模式是向下傳遞的

// 模式強(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;
    }

7.第三方登錄

蘋(píng)果更新的審核規(guī)范中提到使用第三方登錄的APP必須要將apple登錄作為一個(gè)可選擇項(xiàng)

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.

怎么做呢?網(wǎng)上已經(jīng)有很多demo了,此處就不展開(kāi)啦。 附上官方Demo:點(diǎn)我下載

8. App啟動(dòng)過(guò)程中,部分View可能無(wú)法實(shí)時(shí)獲取到frame

可能是為了優(yōu)化啟動(dòng)速度,App 啟動(dòng)過(guò)程中,部分View可能無(wú)法實(shí)時(shí)獲取到正確的frame

// 只有等執(zhí)行完 UIViewController 的 viewDidAppear 方法以后,才能獲取到正確的值,在viewDidLoad等地方 frame Size 為 0,例如:
 [[UIApplication sharedApplication] statusBarFrame];

9. TabBar紅點(diǎn)偏移

如果之前有通過(guò)TabBar上圖片位置來(lái)設(shè)置紅點(diǎn)位置,在iOS13上會(huì)發(fā)現(xiàn)顯示位置都在最左邊去了。遍歷UITabBarButton的subViews發(fā)現(xiàn)只有在TabBar選中狀態(tài)下才能取到UITabBarSwappableImageView,解決辦法是修改為通過(guò)UITabBarButton的位置來(lái)設(shè)置紅點(diǎn)的frame;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容