iOS 13 bug
一, iOS 13 vc present viewcontrolller 时默认人成了 automotic 之前我们直接present 里面 modalPresentationStyle是默认 fullscreen 的 所以现在要适配就不能直接present了
设置vc.modalPresentationStyle = UIModalPresentationFullScreen ;
这样的就好了,至于一些三方的问题,你直接升级就好了。没有升级的看能不看能不能想办法修改下。
二, iOS不允许valueForKey、setValue: forKey获取和设置私有属性,如果有使用会直接导致崩溃 需要使用其它方式修改
[textField setValue:[UIColor red] forKeyPath:@"_placeholderLabel.textColor"];
//替换为
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"输入"attributes:@{NSForegroundColorAttributeName: [UIColor red]}];
三, MPMoviePlayerController 在iOS 13已经不能用了
在使用到MPMoviePlayerController的地方,直接抛了异常:
'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.'
替代方案就是AVPlayerViewController in AVKit.'
四, 即将废弃的 LaunchImage
从 iOS 8 的时候,苹果就引入了 LaunchScreen,我们可以设置 LaunchScreen来作为启动页。当然,现在你还可以使用LaunchImage来设置启动图。不过使用LaunchImage的话,要求我们必须提供各种屏幕尺寸的启动图,来适配各种设备,随着苹果设备尺寸越来越多,这种方式显然不够 Flexible。而使用 LaunchScreen的话,情况会变的很简单, LaunchScreen是支持AutoLayout+SizeClass的,所以适配各种屏幕都不在话下。 注意啦⚠️,从2020年4月开始,所有使⽤ iOS13 SDK 的 App 将必须提供 LaunchScreen,LaunchImage即将退出历史舞台
五,4. iOS 13 DeviceToken有变化‼️
这个很重要⚠️ 可能大多数使用第三方推送的童鞋都不会注意到这个问题,一般现在的第三方推送都是将DeviceToken原始数据丢进去,具体的解析都是第三方内部处理,所以,这些第三方解析DeviceToken的方式正确的话,那就毫无问题。如果你们是通过这种方式来获取DeviceToken,那你需要注意了。(这个坑也是多年前埋下的,很多文章介绍的也是下面这个方法,不规范的做法迟早要还的🤣),如下:
NSString *dt = [deviceToken description];
dt = [dt stringByReplacingOccurrencesOfString: @"<" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @">" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @" " withString: @""];
这段代码运行在 iOS 13 上已经无法获取到准确的DeviceToken字符串了,iOS 13 通过[deviceToken description]获取到的内容已经变了。
{length = 32, bytes = 0x778a7995 29f32fb6 74ba8167 b6bddb4e ... b4d6b95f 65ac4587 }
可以看到,跟原来我们认识的那个已经完全不一样了。其实,造成这样的问题,主要还是没有使用正确的方式来操作,下面是解决办法:
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);
}
六,暗黑模式
iOS13 之前 UIColor只能表示一种颜色,而从 iOS13 开始UIColor是一个动态的颜色,在Light Mode和Dark Mode可以分别设置不同的颜色。
uicolor 实例时多了两个实例方法 ,
照下面操作就好
UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
return [UIColor redColor];
}
else {
return [UIColor greenColor];
}
}];
[self.bgView setBackgroundColor:dyColor];
a,监听模式切换
有时我们需要监听系统模式的变化,并作出响应
那么我们就需要在需要监听的viewController中,重写下列函数
/ 注意:参数为变化前的traitCollection
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection;
// 判断两个UITraitCollection对象是否不同
- (BOOL)hasDifferentColorAppearanceComparedToTraitCollection:(UITraitCollection *)traitCollection;
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
// trait发生了改变
if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
// 执行操作
}
}
还有其他操作请看: https://www.jianshu.com/p/0da3b107f06c