iOS13 SwiftUI使用ScrollViewProxy与@available触发dyld崩溃及解法
问题说明
- 需求:将应用UI从UIKit迁移至SwiftUI,实现视图超出屏幕边界时的自动滚动能力,不考虑包装UIKit的实现方案
- 兼容要求:应用必须支持iOS13系统,自动滚动特性无需对iOS13用户生效,iOS13端不提供该功能属于可接受范围
- 问题表现:直接给
ScrollViewProxy类型的属性加@available(iOS 14.0, *)标记声明时,应用启动直接崩溃:
// 会触发崩溃的写法 @available(iOS 14.0, *) @State var scrollProxy: ScrollViewProxy?
- 崩溃信息:
dyld __abort_with_payload,附带错误描述symbol stub for: type metadata accessor for SwiftUI.ScrollViewProxy
可行实现方案
不需要将ScrollViewProxy本身声明为属性,改为存储滚动调用方法,在需要触发编程式滚动的位置调用即可,从根源上避免iOS13系统加载不存在的SwiftUI类型符号,具体实现步骤如下:
- 声明存储滚动方法的状态属性,该属性不涉及iOS14新增类型,不会触发低版本符号加载错误:
@State var scroll: ((_ id: String, _ anchor: UnitPoint?) -> Void)? = nil
- 在
ScrollViewReader闭包内完成方法赋值,只有iOS14及以上系统运行到此处时才会获取proxy的滚动方法:
ScrollViewReader { proxy in mainBody.onAppear { scroll = proxy.scrollTo } }
- 触发滚动时增加系统版本判断,iOS13下不会执行滚动相关逻辑,不影响低版本正常运行:
if #available(iOS 14.0, *), let scroll = scroll { withAnimation { scroll("callLinkButton", .bottom) } }
内容的提问来源于stack exchange,提问作者NoosaMaan
相关产品推荐
相关产品推荐

