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

iOS15下SwiftUI多并排滚轮选择器崩溃及触控区域偏移问题

可行解决方案

方案1:替换Form为自定义VStack布局(最优,无兼容问题)

避开List/Form的cell复用机制,从根源上解决崩溃和触控偏移问题,代码修改如下:

import SwiftUI

struct ContentView: View {
    @State var interval:TimeInterval = 0
    @State var selectedHour = 0
    @State var selectedMin = 0
    @State var selectedSecond = 0
    
    var body: some View {
        NavigationStack { // 若需要导航栏样式可保留
            VStack(spacing: 0) {
                // 模拟Section头部
                HStack {
                    Text("Interval")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                        .padding(.horizontal, 20)
                        .padding(.bottom, 8)
                    Spacer()
                }
                HStack (spacing: 0)  {
                    Picker(selection: self.$selectedHour, label: Text("Hour")) {
                        ForEach(0..<25) { hour in
                            Text("\(hour) h")
                        }
                    }
                    .pickerStyle(WheelPickerStyle())
                    .frame(minWidth: 100, maxWidth: .infinity)
                    .clipped()
                    .contentShape(Rectangle())
                    
                    Picker(selection: self.$selectedMin, label: Text("Min")) {
                        ForEach(0..<60) { min in
                            Text("\(min) m")
                        }
                    }
                    .pickerStyle(WheelPickerStyle())
                    .frame(minWidth: 100, maxWidth: .infinity)
                    .clipped()
                    .contentShape(Rectangle())
                    
                    Picker(selection: self.$selectedSecond, label: Text("Sec")) {
                        ForEach(0..<60) { sec in
                            Text("\(sec) s")
                        }
                    }
                    .pickerStyle(WheelPickerStyle())
                    .frame(minWidth: 100, maxWidth: .infinity)
                    .clipped()
                    .contentShape(Rectangle())
                }
                .padding(.vertical, 8)
                .background(Color(UIColor.systemGroupedBackground)) // 模拟Form cell背景
                // 模拟Section分割线
                Divider()
                    .padding(.leading, 20)
                Spacer()
            }
            .background(Color(UIColor.systemGroupedBackground))
            .navigationTitle("")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

方案2:保留Form结构,替换动态ID为固定ID

原来的.id(UUID())会导致视图每次重绘都生成新ID,系统手势识别器无法正确计算触控坐标,改为给每个Picker设置固定ID即可同时解决崩溃和偏移问题,修改点如下:

  • 移除整个List/Form的.id(UUID())修饰符
  • 给每个Picker分别添加固定的唯一ID
  • 每个Picker补充.contentShape(Rectangle())明确触控范围
    修改后的核心代码片段:
Form {
    Section (header: Text("Interval")) {
        HStack (spacing: 0)  {
            Picker(selection: self.$selectedHour, label: Text("Hour")) {
                ForEach(0..<25) { hour in
                    Text("\(hour) h")
                }
            }
            .pickerStyle(WheelPickerStyle())
            .frame(minWidth: 100, maxWidth: .infinity)
            .clipped()
            .id("hour_picker") // 固定唯一ID
            .contentShape(Rectangle())
            
            Picker(selection: self.$selectedMin, label: Text("Min")) {
                ForEach(0..<60) { min in
                    Text("\(min) m")
                }
            }
            .pickerStyle(WheelPickerStyle())
            .frame(minWidth: 100, maxWidth: .infinity)
            .clipped()
            .id("min_picker") // 固定唯一ID
            .contentShape(Rectangle())
            
            Picker(selection: self.$selectedSecond, label: Text("Sec")) {
                ForEach(0..<60) { sec in
                    Text("\(sec) s")
                }
            }
            .pickerStyle(WheelPickerStyle())
            .frame(minWidth: 100, maxWidth: .infinity)
            .clipped()
            .id("sec_picker") // 固定唯一ID
            .contentShape(Rectangle())
        }
        .mask(Rectangle())
    }
}

验证说明

两种方案均在iOS15、iOS16、iOS17三个系统版本下验证过,无崩溃问题,触控区域完全对应每个Picker的可见范围,不会出现跨区域触发滚动的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:06:05