You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS15下同个List放多个Wheel样式Picker选第二个时崩溃是什么原因

问题根因

这是iOS 15 系统级的SwiftUI Bug,问题出在SwiftUI内部负责管理视图状态依赖的AttributeGraph框架:

  • iOS15重构了List的单元格复用、可折叠inline控件的布局计算逻辑,当同一个List内存在多个可动态展开/收起的wheel样式Picker时,第二个Picker的选中值发生变化时,会触发两个Picker的布局递归重算,形成依赖循环,你看到的=== AttributeGraph: cycle detected through attribute XXXX ===日志就是循环依赖的直接提示
  • 循环依赖无法被SwiftUI内部打破时,系统会直接杀掉应用进程,所以不会输出常规的崩溃堆栈
  • 该Bug不存在于iOS14,iOS16及后续版本中已经被官方修复,仅需要兼容iOS15的场景需要做额外处理
修复方案

以下方案均兼容iOS14+,不需要做系统版本判断:

  • 方案1:替换List为ScrollView+LazyVStack(改动最小)
    避开List的单元格复用逻辑即可直接解决布局循环问题,视觉效果可以通过调整padding和List的inset样式对齐:
    NavigationView {
        // 替换原有的List为如下代码
        ScrollView {
            LazyVStack(spacing: 12) {
                // 原List内的所有内容原封不动放在此处
            }
            .padding(.horizontal)
        }
        .navigationTitle("Picker")
    }
    
  • 方案2:给每组Picker+触发行套独立Section
    List的Section会隔离内部的布局计算,避免跨Section的依赖循环:
    List {
        Section {
            // Picker1的触发行代码
            if showPicker1 {
                // Picker1原有代码
            }
        }
        Section {
            // Picker2的触发行代码
            if showPicker2 {
                // Picker2原有代码
            }
        }
    }
    .listStyle(.inset)
    
  • 方案3:强制Picker视图重建打断循环
    给每个Picker添加.id()修饰符,绑定对应的选中状态,选中值变化时强制重建Picker视图,直接打断布局循环:
    Picker("", selection: $selected1) {
        // 原有选项逻辑不变
    }
    .pickerStyle(.wheel)
    .clipped()
    .id(selected1) // 新增此行,第二个Picker绑定selected2即可
    

内容的提问来源于stack exchange,提问作者SupaBasti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 17:27:01