iOS15系统适配问题
关于 iOS 15 更新 https://support.apple.com/zh-cn/HT212788
转:https://www.jianshu.com/p/338411df3b33
iOS15系统需要对导航栏进行适配,增加两种appearance,分别是scrollEdgeAppearance
(不滚动时)和standardAppearance
(滚动时)。iOS15系统之前设置导航栏样式后滚动和不滚动是没区别的,现在要实现滚动和不滚动一样的样式必须设置这两种appearance。
下面在控制器里生成一个appearance并赋值给导航栏:(如果需要设置不同的样式可以生成两个appearance对象分别赋值给导航栏)
if (@available(iOS 15.0,*)) { UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init]; self.navigationController.navigationBar.scrollEdgeAppearance = appearance; self.navigationController.navigationBar.standardAppearance = self.navigationController.navigationBar.scrollEdgeAppearance; }
在需要修改样式时可以通过导航栏再获取到这两个appearance,通过appearance修改样式。
注意:
虽然上面生成appearance并且赋值给导航栏时用的是同一个,但是将appearance赋值给导航栏后,导航栏会复制一份,所以导航栏的两种appearance并不是同一个对象。在修改样式时如需修改两种状态下的导航栏样式,必须同时获取到两种appearance再分别进行修改,只获取一个修改是不行的!!!
下面是在某处修改导航栏样式:
if (@available(iOS 15.0,*)) { UINavigationBarAppearance *appearance = self.navigationController.navigationBar.scrollEdgeAppearance; // 设置为不透明 appearance.backgroundEffect = nil; appearance.shadowColor = [UIColor clearColor]; appearance.backgroundImage = [UIImage imageWithColor:[UIColor whiteColor]]; UINavigationBarAppearance *appearance2 = self.navigationController.navigationBar.standardAppearance; // 设置为不透明 appearance2.backgroundEffect = nil; appearance2.shadowColor = [UIColor clearColor]; appearance2.backgroundImage = [UIImage imageNamed:@"test"]; } else { [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"test"] forBarMetrics:UIBarMetricsDefault]; [self.navigationController.navigationBar setShadowImage:[UIImage new]]; //去掉导航下面的线 }
链接:https://www.jianshu.com/p/338411df3b33
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
iOS15适配
iOS15适配主要是以下几点:UINavigationController
、UITabBarController
、sectionHeaderTopPadding
、UIImageWriteToSavedPhotosAlbum
其实iOS13之后就有关于nav和tabbar的新API,但是我测试发现有部分API真正生效还是在iOS15之后,iOS15以前的nav和tabbar的部分API就不适用iOS15之后的了,所以我们这儿判别还是以iOS15来区分。
关于nav和tabbar新的API都涉及到scrollEdgeAppearance
和standardAppearance
,我们直接看怎么用吧(下面的nav为UINavigationController实例)。
UINavigationController
if #available(iOS 15.0, *) { let navAppear = UINavigationBarAppearance() navAppear.configureWithOpaqueBackground() navAppear.backgroundColor = UIColor.red//导航条背景色 //这儿可以设置shadowColor透明或设置shadowImage为透明图片去掉导航栏的黑线 navAppear.shadowColor = UIColor.clear // navAppear.shadowImage = UIColor.clear.asImage(CGSize(width: kScreenW, height: 1.0)) navAppear.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white,NSAttributedString.Key.font: UIFont.systemFont(ofSize: 18.0)] nav.navigationBar.scrollEdgeAppearance = navAppear nav.navigationBar.standardAppearance = navAppear } else { nav.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white,NSAttributedString.Key.font:UIFont.systemFont(ofSize: 18.0)] nav.navigationBar.barTintColor = UIColor.red nav.navigationBar.shadowImage = UIImage() } extension UIColor { func asImage(_ size:CGSize) -> UIImage? { var resultImage:UIImage? = nil let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height) UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale) guard let context = UIGraphicsGetCurrentContext() else { return resultImage } context.setFillColor(self.cgColor) context.fill(rect) resultImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return resultImage } }
UITabBarController
if #available(iOS 15.0, *) { let tabBarAppear = UITabBarAppearance() tabBarAppear.configureWithOpaqueBackground() tabBarAppear.backgroundColor = UIColor.yellow//标签栏背景色 tabBarAppear.stackedLayoutAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.green,NSAttributedString.Key.font:UIFont.systemFont(ofSize: 13.0)] tabBarAppear.stackedLayoutAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.red, NSAttributedString.Key.font:UIFont.systemFont(ofSize: 13.0)] nav.tabBarItem.scrollEdgeAppearance = tabBarAppear nav.tabBarItem.standardAppearance = tabBarAppear } else { self.tabBar.barTintColor = UIColor.yellow }
- 标签栏未选中与选中图依然是设置
nav.tabBarItem.image
和nav.tabBarItem.selectedImage
,标签栏去掉黑线同导航栏方式.
sectionHeaderTopPadding
此属性是iOS15之后提供给UITableView的,默认值22,所以我们要保持原来的单元格起始位置为0,需要重新设置。
if #available(iOS 15.0, *) { self.tableView?.sectionHeaderTopPadding = 0 }
UIImageWriteToSavedPhotosAlbum
iOS15之后UIImageWriteToSavedPhotosAlbum存储图片的回调方法- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo,即使保存成功后此处image返回也为空。
UIImageWriteToSavedPhotosAlbum(UIImage(named: "image")!, self, #selector(image(_:didFinishSavingWithError:contextInfo:)),nil) @objc func image(_ image:UIImage?,didFinishSavingWithError error:NSError?,contextInfo:AnyObject?) { if error != nil { print("保存失败") } else { print("保存成功") } //保存成功这儿的image返回也为空 print(error as AnyObject,image as AnyObject,contextInfo as AnyObject) }
作者:CombatReadiness
链接:https://www.jianshu.com/p/f999349e09c3
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
iOS15适配总结(持续更新)
前言:本文仅提供自己遇到的问题的一些解决方案,想了解更多api的变化可自行搜索。
1.UITableView 分组高度显示异常处理方案
UITableView分组高度默认增加22个像素的高度,导致所有的UI显示异常。
解决方案:
- 全局设置
(推荐)
可以在AppDelegate
中直接全局设置生效,目前未发现不良影响
if (@available(iOS 15.0, *)) {
[UITableView appearance].sectionHeaderTopPadding = 0;
}
- 部分页面设置
针对单独某个UITableView设置
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
}
- Runtime方式(仅提供方案,未验证)
创建UITableView的分类,在+ (void)load
方法中交换initWithFrame:
,并增加如下代码
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
}
2.导航栏显示异常处理方案
iOS15之前的系统,用到了设置导航栏背景颜色的处理,或设置某种颜色或透明或颜色变化,但是在iOS15上全部失效,导致导航栏显示异常。
解决方案:
创建UINavigationController
分类,增加如下方法:
/// 设置导航栏颜色 -(void)setNavigationBackgroundColor:(UIColor *)color{ NSDictionary *dic = @{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : [UIFont systemFontOfSize:18]}; if (@available(iOS 15.0, *)) { // 滚动状态 UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init]; // 设置为不透明 appearance.backgroundEffect = nil; appearance.backgroundImage = [UIImage imageWithColor:color]; appearance.shadowColor = color; appearance.backgroundColor = color; // 静止状态 UINavigationBarAppearance *appearance2 = [[UINavigationBarAppearance alloc] init]; // 设置为不透明 appearance2.backgroundEffect = nil; appearance2.backgroundImage = [UIImage imageWithColor:color]; appearance2.shadowColor = color; appearance2.backgroundColor = color; self.navigationBar.scrollEdgeAppearance = appearance; self.navigationBar.standardAppearance = appearance2; }else{ self.navigationBar.titleTextAttributes = dic; [self.navigationBar setShadowImage:[[UIImage alloc] init]]; [self.navigationBar setBackgroundImage:[UIImage imageWithColor:color] forBarMetrics:UIBarMetricsDefault]; } }
将原来iOS15之前的如下代码:
UIImage *image = [UIImage imageWithColor:color];
[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:image];
修改为:
[self.navigationController setNavigationBackgroundColor:color];
其中color
为当前导航栏的颜色,可根据项目实际情况设置颜色
3.为ProMotion设备配置高刷权限
iPhone 13 Pro、iPhone 13 Pro Max 和 iPad ProMotion 显示器能够在以下各项之间动态切换:
刷新率高达 120Hz,低至 24Hz 或 10Hz 的较慢刷新率。
目前在iPhone 13 Pro 或 iPhone 13 Pro Max 上非官方APP默认不支持120Hz刷新率,其实只需要在Plist上配置以下权限,就可以使用上高刷,而Pad Pro 不需要这种特殊配置,默认支持高刷。
<key>CADisableMinimumFrameDurationOnPhone</key><true/>
作者:Anchoriter
链接:https://www.jianshu.com/p/e1ade38e1882
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
iOS 15适配总结
tabbar及navicationbar的背景颜色问题
问题:从ios14升级到ios15会出现 导航栏背景颜色失效
原因:因为设置颜色方法在ios15中失效
--在iOS13更新的API中新增了针对navigationBar,tabbar分别新增了新的属性专门管理这些滑动时候产生的颜色透明等等信息,由于我们应用兼容iOS10以上,对于导航栏的设置还没有使用UINavigationBarAppearance和UITabBarAppearance,但在更新的iOS15上失效,所以就变得设置失效
//设置navigationBar颜色
self.navigationController.navigationBar.barTintColor = [UIColor blueColor];
//设置tabBar背景色
self.tabBarController.tabBar.backgroundColor = [UIColor blueColor];
//设置tabBarItem字体颜色
NSMutableDictionary<NSAttributedStringKey, id> *normalAttributes = [NSMutableDictionary dictionary];
[normalAttributes setValue:[UIColor blueColor] forKey:NSForegroundColorAttributeName];
[self.tabBarItem setTitleTextAttributes:normalAttributes.copy forState:UIControlStateNormal];
[self.tabBarItem setTitleTextAttributes:normalAttributes.copy forState:UIControlStateSelected];
(滑动显示更多)
解决方法--重新设置相关属性
tabBar
UITabBarAppearance *appearance = [[UITabBarAppearance alloc] init];
//tabBaritem title选中状态颜色
appearance.stackedLayoutAppearance.selected.titleTextAttributes = @{
NSForegroundColorAttributeName:[UIColor blueColor],
};
//tabBaritem title未选中状态颜色
appearance.stackedLayoutAppearance.normal.titleTextAttributes = @{
NSForegroundColorAttributeName:[UIColor blueColor],
};
//tabBar背景颜色
appearance.backgroundColor = [UIColor blackColor];
self.tabBarItem.scrollEdgeAppearance = appearance;
self.tabBarItem.standardAppearance = appearance;
(滑动显示更多)
其中 standardAppearance和scrollEdgeAppearance等的区别
standardAppearance --- 常规状态
scrollEdgeAppearance --- 小屏幕手机横屏时的状态
scrollEdgeAppearance --- 呗scrollview向下拉的状态
(滑动显示更多)
navigationBar
UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
appearance.backgroundColor = [UIColor blackColor];
self.navigationBar.standardAppearance = appearance;
self.navigationBar.scrollEdgeAppearance = appearance;
(滑动显示更多)
tableview新属性
-sectionHeaderTopPadding
官方支持
/// Determines if the table view allows its cells to become focused.
/// When tableView:canFocusRowAtIndexPath: is implemented, its return value takes precedence over this method.
/// Defaults to a system derived value based on platform and other properties of the table view.
@property (nonatomic, getter=isPrefetchingEnabled) BOOL prefetchingEnabled
iOS 15中tableView会给每一个section的顶部(header以上)再加上一个22像素的高度,形成一个section和section之间的间距
(滑动显示更多)
使用
为了配合以前的开发习惯,我们只需要在创建实例的时候进行对间距的设置即可
if (@available(iOS 15.0, *)) {
tableView.sectionHeaderTopPadding = 0;
}
或者全局设置
if (@available(iOS 15.0, *)) {
[UITableView appearance].sectionHeaderTopPadding = 0;
}
(滑动显示更多)
来源:稀土掘金
作者:edwardyk
链接:https://juejin.cn/post/7012558803614826526
iOS15.2 在app初始化时调用该方法 未给相册权限 会导致app卡死 不能启动 会触发iOS 启动看门狗机制 崩溃
在app已经启动后 调用该方法 未给相册权限 会导致页面卡死 不能使用
[PHPhotoLibrary.sharedPhotoLibrary registerChangeObserver:self]
iOS15.2 以前使用该通知是不需要相册权限的 15.2之后 苹果添加了应用隐私报告 添加了该方法的相册权限前提
解决方案: 先请求相册权限 在获取到权限后 同时将注册该通知放到异步注册
if (@available(iOS 14, *)) {
[PHPhotoLibrary requestAuthorizationForAccessLevel:PHAccessLevelReadWrite handler:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized)
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[PHPhotoLibrary.sharedPhotoLibrary registerChangeObserver:self];
});
}
}];
}else {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status){
if (status == PHAuthorizationStatusAuthorized)
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[PHPhotoLibrary.sharedPhotoLibrary registerChangeObserver:self];
});
}
}];
}
- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
/// 相应的业务 再回到主线程处理 如果需要的话
__weak typeof (self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
});
}
在iOS15中,UINavigationBar默认是透明的,有滑动时会逐渐变为模糊效果,可以通过改变scrollEdgeAppearance属性直接变为模糊效果
UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init]; appearance.backgroundEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular]; self.navigationBar.scrollEdgeAppearance = appearance;
UIBarAppearance 详细:https://www.jianshu.com/p/0ac6411421c2
UIBarAppearance是iOS13苹果新出来的一个对相应的空间统一设置外观样式的API,可以统一配置NavigationBar 、TabBar、 Toolbar等的外观样式。 UIBarAppearance的子类 UINavigationBarAppearance 设置导航栏外观样式 UITabBarAppearance 设置Tabbar外观样式 UIToolbarAppearance 设置Toolbar外观样式 这里用导航条的UINavigationBarAppearance作为示例,TabBar和Toolbar的设置外观样式使用的方式与其相同 1.UINavigationBar默认外观样式 iOS15以前默认是半透明毛玻璃 iOS15以后默认是透明,在滑动时如果系统检测到导航栏下方有其他UI的话,导航栏会变成半透明毛玻璃,想要默认半透明毛玻璃,设置standardAppearance和scrollEdgeAppearance,单独设置standardAppearance也不行 let navBarAppearance = UINavigationBarAppearance() navigationBar.scrollEdgeAppearance = navBarAppearance navigationBar.standardAppearance= navBarAppearance 2.UINavigationBar相关属性说明 barTintColor 导航栏背景颜色 iOS15以前设置有效果 iOS15以后无效果需要设置UINavigationBarAppearance的backgroundColor tintColor 导航栏文字 颜色 isTranslucent 半透明 默认为YES,当设为YES,iOS15以前先取barTintColor的颜色,当barTintColor为nil默认半透明毛玻璃,iOS15先取UINavigationBarAppearance的backgroundColor颜色,当UINavigationBarAppearance的backgroundColor为nil,UINavigationBarAppearance的backgroundEffect默认半透明毛玻璃,当UINavigationBarAppearance的backgroundEffect为nil背景为透明 当设为NO,iOS15以前先取barTintColor的颜色,当barTintColor为nil默认白色,iOS15先取UINavigationBarAppearance的backgroundColor颜色,当UINavigationBarAppearance的backgroundColor为nil,UINavigationBarAppearance的backgroundEffect默认背景为灰色,当UINavigationBarAppearance的backgroundEffect为nil背景为黑色 shadowImage 下划线 iOS13以前设置有效果,不过需要同时设置backgroundImage,会影响导航栏背景,不建议 iOS13以后无效果需要设置UINavigationBarAppearance的shadowColor和shadowImage scrollEdgeAppearance iOS15 当可滚动内容的边缘与导航栏的边缘对齐时,导航栏的外观设置。如果这个属性的值为nil, UIKit使用导航栏的standardAppearance外观属性的值,修改为有一个透明的背景 standardAppearance iOS13 设置导航栏标准高度的样式设置,默认样式。此属性的默认值是一个包含系统默认外观设置的外观对象 3.UINavigationBarAppearance相关属性说明 backgroundEffect 半透明效果,基于backgroundColor或backgroundImage的磨砂效果 backgroundColor 背景色 backgroundImage 背景图片 backgroundImageContentMode 渲染backgroundImage时使用的内容模式。 默认为UIViewContentModeScaleToFill。 shadowColor 阴影颜色(底部分割线),当shadowImage为nil时,直接使用此颜色为阴影色。如果此属性为nil或clearColor(需要显式设置),则不显示阴影 shadowImage 阴影图片
其他相关ios 15适配问题的文章:
IOS 15 导航栏设置无效的解决方案 https://zhuanlan.zhihu.com/p/435990224
IOS 15 导航栏返回按钮文字隐藏失效问题 https://wenku.baidu.com/view/a9e44ba06b0203d8ce2f0066f5335a8102d2667c.html?_wkts_=1667445200301
ios15 导航栏设置透明效果无效 https://www.icode9.com/content-4-1225799.html
导航栏setBackgroundImage在iOS15上不起作用 https://cloud.tencent.com/developer/ask/sof/1210913
iOS 15的坑:解决tabbar变透明了 http://events.jianshu.io/p/964bf8535067
iOS 15 特性及适配 http://t.zoukankan.com/shisishao-p-15324488.html
iOS15问题汇总 https://www.jianshu.com/p/a020ebc8c0b1
iOS15开发 访问相册权限问题This app has crashed because it attempted to access privacy-sensitive data without
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战