在菜单 - 选择器中滚动时,在滚动中间释放点击会导致其继续跳到顶部

问题描述 投票:0回答:1
struct PlainTextPicker<T: Hashable>: View
{
    @Binding var selection: T?
    let defaultString: String?
    var options: [T]
    var toLabel: (T) -> String

    // body
    Menu
    { 
        Picker("Select", selection: $selection)
        {
            if let defaultString = defaultString
            {
                 Text(defaultString).tag(nil as T?)
            }
                
            ForEach(options, id:\.self)
            {   option in
                Text(toLabel(option)).tag(option as T?)
            }
        } label: 
        {
            HStack
            {
                Text(getSelectionText())
            }
        }
    }
}
PlainTextPicker(selection: $selectedStall, 
                options: ItemsInformation.shared.getItems(customer, category: category),
                defaultString: "Please Select Item",
                toLabel: {"\($0.code) \($0.name)"})

SwiftUI / iOS 16.4+
中,我使用选取器作为菜单中的标签,如上面的代码所示。在特定视图中,当选取器的总大小(可以进行选择的区域)大于屏幕并需要滚动时,在滚动时释放点击会导致选取器跳到顶部。

我怀疑重绘是由于特定可观察属性的变化而发生的。因此,我检查了可能触发重绘的变量变化,例如

@State
@ObservedObject
@StateObject
。此外,我正在使用计时器,即使我停止计时器,同样的问题仍然存在。因此,尽管变量没有变化,但视图似乎正在重新绘制。我正在寻求关于哪些情况值得怀疑的建议。

swiftui redraw observedobject jump-list swiftui-picker
1个回答
0
投票

首先,我要向那些提供建议的人表示感谢。

我正在使用以下视图来形式化列表格式。

struct SampleList<T: Identifiable, Content: View>: View
{
    @Binding var datas: [T]
    let attributes: [ListTextAttribute]
    let row: (T) -> Content
    
    var width: CGFloat
    {
        return self.attributes.reduce(0){$0 + $1.width}
    }
    
    init(rows: Binding<[T]>,
         attributes: [ListTextAttribute],
         @ViewBuilder customRow: @escaping ((T) -> Content))
    {
        _datas = rows
        self.attributes = attributes
        self.row = customRow
    }
    
    
    var div: some View
    {
        RoundedRectangle(cornerRadius: 8)
            .frame(height: 2)
    }
    
    
    var body: some View
    {
        VStack
        {
            // header
            HStack(spacing: 0)
            {
                ForEach(self.attributes)
                {   attribute in
                    attribute.getTextRow()
                }
            }
            .frame(width: width, height: 40)
            
            // list
            ScrollView(showsIndicators: false)
            {
                LazyVStack(spacing: 0)
                {
                    ForEach(datas)
                    {   data in
                        
                        row(data)
                        div
                    }
                }
            }
            .frame(width: width)
        }
    }
}

在给定的代码中,我不确定确切的原因,但由于特定视图中

attributes
中的值,似乎会发生连续重绘。

作为解决方案,我将使用此列表的视图重构为新的

Struct: View
并调用它,以便重绘仅发生在与该列表对应的视图中。

如果您对这个问题有任何可能的原因,如果您能分享,我将不胜感激。谢谢你

© www.soinside.com 2019 - 2024. All rights reserved.