iOS 15下SwiftUI使用contextMenu出现[UICollectionViewRecursion]奇怪警告
警告产生原因
该警告是iOS 15系统SwiftUI的内部实现缺陷导致,和业务代码逻辑没有直接关联:
- SwiftUI在iOS 15版本中,
contextMenu修饰符的底层实现依赖UIKit的UICollectionView,系统渲染上下文菜单的预览图层时,会触发UICollectionView的递归布局调用,系统为了避免出现无限递归崩溃,主动禁用了递归触发日志,就输出了这条提示:
[UICollectionViewRecursion] cv == 0x10481a000 Disabling recursion trigger logging
- 该警告本身属于无害提示,不会导致App崩溃,也不会影响上下文菜单的正常功能使用,仅会出现在iOS 15版本上,iOS 16及以上系统已经修复了这个内部问题,不会再抛出该警告。
解决方案
- 方案1(最推荐,改造成本最低):给iOS 15版本的
contextMenu附加一个空的onTapGesture修饰符作为垫片,破坏系统内部递归布局的触发条件,即可消除警告:
// 写法1:直接做版本判断 if #available(iOS 16, *) { yourView.contextMenu { // 你的菜单内容代码 } } else { yourView.contextMenu { // 你的菜单内容代码 } .onTapGesture {} } // 写法2:用扩展简化链式调用 extension View { func fixIOS15ContextMenuWarning() -> some View { if #available(iOS 15, *) { return AnyView(self.onTapGesture {}) } return AnyView(self) } } // 调用时直接加修饰符即可 yourView .contextMenu { /* 菜单内容 */ } .fixIOS15ContextMenuWarning()
- 方案2:如果App的用户群体中iOS 15版本占比极低,可以直接将App的最低兼容版本提升到iOS 16,该警告会自动消失。
- 方案3:替换系统原生的
contextMenu为自定义实现的上下文菜单组件,彻底规避系统bug,仅适合对调试日志纯净度要求极高的场景,改造成本较高。
内容的提问来源于stack exchange,提问作者iaomw
相关产品推荐
相关产品推荐

