Row of Picker wheels in SwiftUI, why are drag-to-scroll areas offset from Picker controls on screen?

吃可爱长大的小学妹 提交于 2020-06-27 12:52:29

问题


I'm working on a SwiftUI view whose purpose is to allow the user to enter an amount of dollars. I want a row of seven wheel-style Pickers, each of whose values are the digits 0 to 9.

The following code works, except that when I try to touch & drag a digit column to scroll through it, I find that my drag gesture causes not the Picker I'm touching to scroll, but rather a Picker several columns over to the right. To put it another way, the drag-to-scroll area for each Picker is offset quite a bit to the left of where the Picker column itself appears on the screen.

I've tried putting borders on the views, but everything seems to be in the right place. Any ideas what's causing this or how to fix it?

import SwiftUI

struct CurrencyPickerView: View {

    @State private var centsDigit: Int = 0
    @State private var tenCentsDigit: Int = 0
    @State private var onesDigit: Int = 0
    @State private var tensDigit: Int = 0
    @State private var hundredsDigit: Int = 0
    @State private var thousandsDigit: Int = 0
    @State private var tenThousandsDigit: Int = 0

    var body: some View {
        let pickerWidth = CGFloat(20)
        return HStack {
            Picker(selection: $tenThousandsDigit, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
            }.frame(width: pickerWidth)

            Picker(selection: $thousandsDigit, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
            }.frame(width: pickerWidth)

            Picker(selection: $hundredsDigit, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
            }.frame(width: pickerWidth)

            Picker(selection: $tensDigit, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
            }.frame(width: pickerWidth)

            Picker(selection: $onesDigit, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
            }.frame(width: pickerWidth)

            Text(".")

            Picker(selection: $tenCentsDigit, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
            }.frame(width: pickerWidth)

            Picker(selection: $centsDigit, label: EmptyView()) {
                ForEach((0...9), id: \.self) { ix in
                    Text("\(ix)").tag(ix)
                }
            }.frame(width: pickerWidth)

        }
    }
}

回答1:


Applying .clipped() to each .frame(...) solved the problem. Presumably the touch areas for these Picker wheels were being presented outside the frame area (which is used for layout but does not inherently constrain content to the frame bounds) and were overlapping in ways that caused the weird offset effect. Using .clipped() keeps SwiftUI from displaying/activating content outside the frame, and now the Picker wheels work correctly.



来源:https://stackoverflow.com/questions/58438050/row-of-picker-wheels-in-swiftui-why-are-drag-to-scroll-areas-offset-from-picker

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!