技术参考:
apple login
IOS13适配-详细
iOS 13 适配(持续更新中)
iOS13适配
掘金 iOS 13适配01
掘金 适配 iOS13
iOS 13 更新tips
View Controller Presentation Changes in iOS 13
附上官方Demo:下载地址
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
// 暗黑模式
}
else {
// 正常模式
}
// 注意:参数为变化前的traitCollection
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection;
// 判断两个UITraitCollection对象是否不同
- (BOOL)hasDifferentColorAppearanceComparedToTraitCollection:(UITraitCollection *)traitCollection;
info.plist 内APP级别禁用暗黑模式
Key: User Interface Style
value: Light
widow级别的禁用暗黑模式
if (@available(iOS 13.0, *)) {
[UIApplication sharedApplication].keyWindow.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
}
ViewController级别禁用暗黑模式
想全局禁用需要在 baseVC内全局禁用
#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
- (UIUserInterfaceStyle)overrideUserInterfaceStyle{
return UIUserInterfaceStyleLight;
}
#endif
view级别禁用暗黑模式
view.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
参考这里 :iOS开发如何适配暗黑模式(Dark Mode)
+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
- (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
[UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trait) {
if (trait.userInterfaceStyle == UIUserInterfaceStyleDark) {
return UIColorRGB(0x000000);
} else {
return UIColorRGB(0xFFFFFF);
}
}];
modalPresentationStyle
属性默认不是UIModalPresentationFullScreen
了,需要根据需求手动设置。
LXNavigationViewController *nav = [[LXNavigationViewController alloc] initWithRootViewController:loginViewController];
nav.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:nav animated:YES completion:nil];
全局hook presentViewController
方法
+ (void)hoookPresentFuc{
[UIViewController aspect_hookSelector:@selector(presentViewController:animated:completion:) withOptions:AspectPositionBefore usingBlock:^(id aspectInfo){
UIViewController *presentingVC = (UIViewController *)aspectInfo.arguments.firstObject;
presentingVC.modalPresentationStyle = UIModalPresentationFullScreen;
} error:NULL];
}
_placeholderLabel.textColor
私有属性被禁止访问[self.textField setValue:self.placeholderColor forKeyPath:@"_placeholderLabel.textColor"];
崩溃信息:
'Access to UITextField's _placeholderLabel ivar is prohibited.
This is an application bug'
UITextField有个attributedPlaceholder的属性,我们可以自定义这个富文本来达到我们需要的结果。
NSMutableAttributedString *placeholderString = [[NSMutableAttributedString alloc] initWithString:placeholder attributes:@{NSForegroundColorAttributeName : self.placeholderColor}];
_textField.attributedPlaceholder = placeholderString;
if (@available(iOS 13.0, *)) {
if (textField.attributedText.length > 0) {
color = textField.attributedText.color;
}
}else{
color = [textField valueForKeyPath:@"_placeholderLabel.textColor"];
}
iOS 13 通过 KVC 方式修改私有属性,有 Crash 风险,谨慎使用!并不是所有KVC都会Crash,要尝试!
UINavigation+SXFixSpace
if ([NSStringFromClass(subview.class) containsString:@"ContentView"]) {
// 结构调整后 在这里return掉
if (@available(iOS 13.0, *)) {
if ([NSStringFromClass(subview.class) containsString:@"_UINavigationBarContentView"]) {
return;
}
}
//可修正iOS11之后的偏移
subview.layoutMargins = UIEdgeInsetsMake(0, space, 0, space);break;
}
同时,下面的属性也已经被禁止访问了:
[barBgView valueForKey:@"_shadowView"];
[barBgView valueForKey:@"_backgroundEffectView"];
UIStatusBarStyleDefault
枚举值代表含义有变化
typedef NS_ENUM(NSInteger, UIStatusBarStyle) {
UIStatusBarStyleDefault = 0, // 根据用户交互样式自动选择状态条样式
UIStatusBarStyleLightContent API_AVAILABLE(ios(7.0)) = 1, // Light content, for use on dark backgrounds
UIStatusBarStyleDarkContent API_AVAILABLE(ios(13.0)) = 3, // Dark content, for use on light backgrounds
UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,
UIStatusBarStyleBlackOpaque NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,
} API_UNAVAILABLE(tvos);
定制状态条的样式 使用apple 推荐的这个系统方法
// ios 13.0 之后,这个方法已经失效了
// [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
- (UIStatusBarStyle)preferredStatusBarStyle {
if (@available(iOS 13.0, *)){
return UIStatusBarStyleDarkContent;
}
return UIStatusBarStyleDefault;
}
或者 ------>>:
UIStatusBarStyleDefault
替换为
(@available(iOS 13.0, *) ? UIStatusBarStyleDarkContent : UIStatusBarStyleDefault)
如果你还是使用的Xcode 10 为了走过编译器这一步,可以使用预编译命令,这么写:
#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
if (@available(iOS 13.0, *)) {
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDarkContent];
}else{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}
#else
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
#endif
UISearchBarBackground
,禁止访问和removeif ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
if (@available(iOS 13.0, *)) {
subview.backgroundColor = [UIColor lightGrayColor];
// subview.layer.contents = nil;
}else{
[subview removeFromSuperview];
}
}
info.plist
文件下
Key: NSBluetoothAlwaysUsageDescription
Value: 我们要一直使用您的蓝牙,具体做什么别问我
#include
- (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);
}
An app that fails to meet any of the above requirements receives the following return value:
- An app linked against iOS 12 or earlier receives a dictionary with pseudo-values. In this case, the SSID is Wi-Fi (or WLAN in the China region), and the BSSID is 00:00:00:00:00:00.
- An app linked against iOS 13 or later receives NULL.
-
iOS13 以后只有开启了 Access WiFi Information capability,才能获取到 SSID 和 BSSID
参考:CNCopyCurrentNetworkInfo
App启动过程中,部分View可能无法实时获取到frame。
iOS 13以前 document.body.scrollHeight iOS 13中 document.documentElement.scrollHeight 两者相差55 应该是浏览器定义高度变了
github fishhook
'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.'
从 iOS 8 的时候,苹果就引入了 LaunchScreen,我们可以设置 LaunchScreen来作为启动页。当然,现在你还可以使用LaunchImage来设置启动图。不过使用LaunchImage的话,要求我们必须提供各种屏幕尺寸的启动图,来适配各种设备,随着苹果设备尺寸越来越多,这种方式显然不够 Flexible。而使用 LaunchScreen的话,情况会变的很简单, LaunchScreen是支持AutoLayout+SizeClass的,所以适配各种屏幕都不在话下。
注意啦⚠️,从2020年4月开始,所有使⽤ iOS13 SDK 的 App 将必须提供 LaunchScreen,LaunchImage即将退出历史舞台。
遍历视图获取 keywindow 的方式会失效。
新增了 screenWindow 自定义视图和 keywindow之间新增iOS 13系统的特有图层。