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

自定义WheelPicker滚动无法显示2、3项问题求助(iOS/macOS)

自定义WheelPicker滚动定位异常问题

我正在开发自定义WheelPicker,核心功能已完成,但出现异常:滚动时无法定位到第2、3项,但点击可以选中这两项,该问题在iOS和macOS系统上均能复现。

WheelPicker 滚动异常演示

测试视图代码

struct TestWheel: View {
    @State var t: Int! = 1
    var tList = [1,2,3,4,5,6,7,8,9,10,11,12]
    
    var body: some View {
        #if os(iOS)
        if #available(iOS 17.0, *) {
            UksWheelPicker(selected: $t, items: tList, config: UksWheelConfig(itemHeight: 32)) {
                Text("Text - \($0)")
                    .frame(width: 100)
            }
        }
        #endif
        
        #if os(macOS)
        if #available(macOS 14.0, *) {
            UksWheelPicker(selected: $t, items: tList, config: UksWheelConfig(itemHeight: 32)) {
                Text("Text - \($0)")
                    .frame(width: 100)
            }
        }
        #endif
    }
}

自定义WheelPicker代码

import SwiftUI
import Essentials

@available(macOS 14.0, *)
@available(iOS 17.0, *)
public struct UksWheelPicker<T, ItemView>: View where T: CustomStringConvertible, T: Hashable, ItemView: View {
    @Binding var selected: T?
    var items: [T]
    
    let config: UksWheelConfig
    
    var itemView: (T) -> ItemView
    
    public init(selected: Binding<T?>, items: [T], config: UksWheelConfig, itemView: @escaping (T) -> ItemView) {
        _selected = selected
        self.items = items
        self.config = config
        self.itemView = itemView
    }
    
    public var body: some View {
        ScrollViewReader { reader in
            ScrollView(.vertical) {
                LazyVStack(spacing: 0) {
                    SpacingElem()
                        .id("_______1__")
                    
                    ForEach(items, id: \.self) { item in
                        itemView(item)
                            .frame(height: config.itemHeight)
                            .id(item)
                            .onTapGesture {
                                withAnimation {
                                    selected = item
                                }
                            }
                    }
                    
                    SpacingElem()
                        .id("_______2__")
                }
                .scrollTargetLayout()
            }
            .scrollTargetBehavior(.viewAligned)
            .scrollIndicators(.hidden)
            .scrollPosition(id: $selected, anchor: .center)
            .frame(height: config.itemHeight * 7)
            .mask(LinearGradient(gradient: Gradient(colors: [.clear, .clear, .black, .black, .clear, .clear]), startPoint: .top, endPoint: .bottom))
            .onAppear {
                scrollToNeededElem(reader: reader)
            }
        }
    }
}

//////////////////////
///HELPER VIEWs
/////////////////////

@available(macOS 14.0, *)
@available(iOS 17.0, *)
extension UksWheelPicker {
    @ViewBuilder
    private func SpacingElem() -> some View {
        Spacer()
            .frame(width: 100, height: config.itemHeight * 3)
    }
}

//////////////////////
///HELPERS
/////////////////////

@available(macOS 14.0, *)
@available(iOS 17.0, *)
extension UksWheelPicker {
    func scrollToNeededElem(reader: ScrollViewProxy) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            withAnimation {
                if let selected {
                    reader.scrollTo(selected, anchor: .center)
                }
            }
        }
    }
}

public struct UksWheelConfig {
    public let itemHeight: CGFloat
    public let selectionEnabled: Bool
    public let selectionColor: Color?
    public let selectionIsOverlay: Bool
    
    public init(itemHeight: CGFloat, selectionEnabled: Bool = true, selectionColor: Color? = nil, selectionIsOverlay: Bool = false) {
        self.itemHeight = itemHeight
        self.selectionEnabled = selectionEnabled
        self.selectionColor = selectionColor
        self.selectionIsOverlay = selectionIsOverlay
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:10:59