iOS 26 适配笔记

20,082 阅读6分钟

这是适配iOS 26的笔记,并非介绍新功能和API。陆续更新,发现一个就写一个...

如何在 iOS 26 使用自定义TabBar?

发现很多小伙伴想在 iOS 26 中使用自定义的TabBar,目前系统貌似没有开放相关接口实现。不过方法总比问题多嘛,我这里写了个基本还原以往效果的Demo,具体实现比较简单粗暴,需要的话可以参考一下我的Demo:ClassicTabBarUsingDemo

  • 主要实现代码可在Demo中搜索“📌”查看,具体实现过程可以看看我这篇小文章

全屏返回手势

iOS 26 的导航控制器navigationController会自带全屏返回手势:interactiveContentPopGestureRecognizer,整个控制器View的区域都可以响应返回手势(相当于把FDFullscreenPopGesture直接内置了🤫),并且会自动识别手势冲突的情况,例如碰到了UIScrollView就会自动失效。

但是如果在诸如touchesMoved方法做一些手势响应处理的话就不行了,会触发返回手势的,这种情况就只能手动关闭了:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    if #available(iOS 26.0, *) {
        navigationController?.interactiveContentPopGestureRecognizer?.isEnabled = false
    }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if #available(iOS 26.0, *) {
        navigationController?.interactiveContentPopGestureRecognizer?.isEnabled = true
    }
}
  • 或者在手势代理方法里面按照自己的条件开启或关闭。

PS:这个全屏返回手势可以不断触发的哦,意思是在当前控制器返回的过程中还可以继续滑,上一个控制器也能接着一起返回(以前动画过程中无法响应手势),也就是说只要滑得快就能一下子回到根控制器,要注意一下。

UIScrollView的边缘效果

iOS 26 UIScrollView会自带边缘效果:

滚动时会在边缘处自动带上一些模糊效果以突出导航栏元素,是个很好的视觉效果。

不过不知道为什么通过代码对scrollView进行形变(例如旋转和缩放),这个边缘效果也会自动出现(可能是Beta版的原因)!这对我的裁剪工具影响极大🤬:

好在可以关闭这个边缘效果:

if #available(iOS 26.0, *) {
    scrollView.topEdgeEffect.isHidden = true
}

Liquid Glass 液态玻璃

iOS 26 之后系统常用控件都会采用新的液态玻璃UI,例如UINavigationBarUITabBar等,并且是【强制性】的!。

不过目前可以暂时关闭(毕竟需要时间去好好适配🥹),只要在info.plist加上这一项即可:

<key>UIDesignRequiresCompatibility</key>
<true/>

但是在WWDC上也说了:

2081749803298.jpg

  • 也就是说最多只给一年时间(死缓😑)。

首先是系统导航栏,现在导航栏按键都会有个玻璃罩子:

2311757957068.jpg

  • 这些玻璃罩子都是有交互的,目前还是强制性显示,无法隐藏。

如果实在不想用或者不够时间改的话,其实大部分都还好,大体布局都差不多,况且一般都是用自定义的吧,可能都用不着。

但是!UITabBar估计就很多人都用着,这个是完全大变样,如果是自定义的tabBar就更麻烦了。

  1. 第一种通过设置私有属性tabBar修改成自定义tabBar,会被直接干没,估计因为你目前的自定义tabBar不是液态玻璃:

2041749801816.jpg

  1. 另一种是在系统tabBar上添加自定义tabBar,虽然能看到,但是已经变成个纯摆设了,因为手势响应都被系统tabBar拦截了,而且触碰时还自带了液态玻璃的交互效果:

2071749802975.jpg

  • 还有像以前那种在中间放个大按钮的方式也不行了,根本无法响应。

事已至此,看来真的只能去适配新的设计了。对我来说挺好的🙃,换一种风格,有新鲜感,就是学习成本有点高😤。

  • PS1:新版的UINavigationBarUITabBar可以放入更多按键和定制化,还可以切换不同的排版布局,只不过UI和动效都是系统的,无法自定义。
  • PS2:我写了个如何在 iOS 26 使用自定义TabBar的Demo:ClassicTabBarUsingDemo,有需要可以去参考一下,具体实现过程可以看看我这篇小文章

发现个宝藏Demo:GlassExplorer,作者用了OC的黑魔法让我们去调试不同的玻璃参数,可以更好地去了解各种玻璃效果~(注意修改的都是私有属性,可别拿去发版...)

1901749699087.jpg

hidesBottomBarWhenPushed对新TabBar不起效

在最新版的 Xode 26 beta 中已修复,会自动隐藏了。

只不过新版的UITabBar是叠加形式的,当手势侧滑返回时,不会像以前那样显示上一个VC的界面上,而是盖在最上面:

2291757954409.jpg

「怪异」字符在 iOS 26 会崩溃!

📢📢📢 最新的 iOS 26.0.1 版本已经修复!强烈建议更新!

20251001054901.jpg

以下是回顾:

⚠️ 当系统为iOS 26时,一旦App出现诸如这种字符串就会崩溃:

20250926011058.jpeg

  • 图中字符来自开发者向苹果的反馈

如果已经更新了iOS 26,可千万不要把这些怪异字符发到App!否则例如微信、企业微信、甚至连苹果自己的备忘录等App就会打开即闪退! 别问我为什么知道😭

崩溃日志如下:

CoreText:
std::__1::__hash_table<std::__1::__hash_value_type<long, CGPoint>, std::__1::__unordered_map_hasher<long, std::__1::__hash_value_type<long, CGPoint>, std::__1::hash<long>, std::__1::equal_to<long>, true>, std::__1::__unordered_map_equal<long, std::__1::__hash_value_type<long, CGPoint>, std::__1::equal_to<long>, std::__1::hash<long>, true>, std::__1::allocator<std::__1::__hash_value_type<long, CGPoint>>>::erase(std::__1::__hash_const_iterator<std::__1::__hash_node<std::__1::__hash_value_type<long, CGPoint>, void*>*>) + 300

从崩溃日志上看,大部分情况是来自对怪异字符进行文本计算(boundingRectWithSize)时触发的,也有部分是在渲染时(例如显示在UILabel上)触发的。

在以前的 iOS 版本可能会小概率崩溃,但在iOS 26 就是【100%崩溃】,有可能是CoreText的内部实现有所变化,问ChatGPT的回答是:

    CoreText 在处理一些「超出 Unicode 标准范围」或者「非法组合」的字符时,内部可能会生成异常的 glyph/position 数据,然后存到类似 unordered_map<long, CGPoint> 的结构里。
    一旦这些“异常 key”或“非法索引”进入 hash 表,再触发 erase 或 rehash,就可能导致崩溃。
    iOS 26 上 libc++ 的实现可能更严格或者更容易暴露这个问题,所以才表现出来。

至于怎么修复?这已经超出我的知识范围了... 等苹果修复?起码得一个月😅。

如果跟我一样不懂这些底层原理,就只能先去寻求AI的帮助了,让AI帮忙分析如何去清洗这些怪异、非法的字符,并封装好方法和工具专门处理这些怪异字符(个人建议最好在网络层接收字符串时就对其做好清理)。

clockHandRotationEffect 在最新版的 Xcode 中失效

用着clockHandRotationEffectClockHandRotationKitSwingAnimation)这个API的小伙伴们要注意啦,在最新版的 Xcode 26.1.1 中该API会失效!也就是小组件无法动起来了!🤯

🫠 不过好在旧版Xcode(例如26.0.1)运行的项目还是能使用的~

🥶 果然使用私有API还是有风险呢。

陆续更新...

发现一个写一个😇