iOS13 适配问题

1. 控制器的 modalPresentationStyle 默认值变了

有用户反映升级 iOS13 后, 界面跳转变成了小卡片...

查阅了下 UIModalPresentationStyle枚举定义, 发现苹果直接将modalPresentationStyle 默认值改成这个,有点不解;
默认动画 UIModalPresentationAutomatic;
如果想要恢复原来交互动画的话,
需要设置一下modalPresentationStyle 属性;

nav.modalPresentationStyle = UIModalPresentationFullScreen;

当然,我们可以通过方法交换,来达到全局修改的目的:

@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 {
    //设置满屏,不需要小卡片
    if(@available(iOS 13.0, *)) {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen;
    }
    [self cx_presentViewController:viewControllerToPresent animated:flag completion:completion];
}

2. KVC限制

iOS13不能通过KVC的方式随意修改一些没有暴露出来的属性了.

比如常用的 TextField_placeholderLabel.textColorUISearchBar_searchField会报如下类似的错误;

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

还有statusBar

通过以下方式获取statusBar的方式已经不可取了,iOS13上继续使用会造成crash。

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

报错信息如下:

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对象;

3.iOS 13 推送 DeviceToken的变化

可能大多数使用第三方推送的童鞋都不会注意到这个问题,一般现在的第三方推送都是将DeviceToken原始数据丢进去,具体的解析都是第三方内部处理,所以,这些第三方解析DeviceToken的方式正确的话,那就毫无问题。如果你们是通过这种方式来获取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,需要用户开启定位权限或者使用新的API NEHotspotConfiguration获取

5. MPMoviePlayerController 在iOS 13已经不能用了

在使用到MPMoviePlayerController的地方,直接抛了异常

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

如何修改: 这个没啥好说的,既然不能再用了,那只能换掉了。替代方案就是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

关于Dark Mode,这里补充几点。

因为苹果目前还没有强制必须适配这个,相信大家的很多项目也没有开始是配这个模式。所以,前期可以强制Light模式。不然,你可能会遇到一些问题,比如UITableViewCell的背景色,如果你没有设置过背景色的话,它在Dark模式下就是黑色的,再比如UIDatePicker文字颜色等等。

那么怎么强制模式呢?

iOS 13给UIView和UIViewController都添加了一个属性:

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

给这个属性设置成某一种模式,即可强制显示模式。
如果你想修改一处,应用所有地方,那么你只需要设置widow的显示模式即可,这会影响widow下面的所有视图显示模式,这也可以看出显示模式是向下传递的

// 模式强制切换
if (darkMode) {
    if (@available(iOS 13.0, *)) {
        [UIApplication sharedApplication].keyWindow.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
    }
} else {
    if (@available(iOS 13.0, *)) {
        [UIApplication sharedApplication].keyWindow.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
    }

7.第三方登录

苹果更新的审核规范中提到使用第三方登录的APP必须要将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.

怎么做呢?网上已经有很多demo了,此处就不展开啦。 附上官方Demo:点我下载

8. App启动过程中,部分View可能无法实时获取到frame

可能是为了优化启动速度,App 启动过程中,部分View可能无法实时获取到正确的frame

// 只有等执行完 UIViewController 的 viewDidAppear 方法以后,才能获取到正确的值,在viewDidLoad等地方 frame Size 为 0,例如:
 [[UIApplication sharedApplication] statusBarFrame];

9. TabBar红点偏移

如果之前有通过TabBar上图片位置来设置红点位置,在iOS13上会发现显示位置都在最左边去了。遍历UITabBarButton的subViews发现只有在TabBar选中状态下才能取到UITabBarSwappableImageView,解决办法是修改为通过UITabBarButton的位置来设置红点的frame;

你可能感兴趣的:(iOS13 适配问题)