SwiftUI-在HStack中并排放置两个选择器不会调整选择器的大小

gra*_*ell 2 picker swiftui hstack

我的目标是将两个选择器水平并排放置,每个选择器占用屏幕的一半宽度。想象一下UIPickerView,它适合屏幕的宽度,并且具有两个宽度相等的组件-这就是我试图在SwiftUI中重新创建的组件。

由于SwiftUI中的选择器当前不允许使用多个组件,因此对我来说,显而易见的替代方案是将两个选择器放置在内HStack

这是来自测试项目的一些示例代码:

struct ContentView: View {
    @State var selection1: Int = 0
    @State var selection2: Int = 0

    @State var integers: [Int] = [0, 1, 2, 3, 4, 5]

    var body: some View {
        HStack {
            Picker(selection: self.$selection1, label: Text("Numbers")) {
                ForEach(self.integers) { integer in
                    Text("\(integer)")
                }
            }
            Picker(selection: self.$selection2, label: Text("Numbers")) {
                ForEach(self.integers) { integer in
                    Text("\(integer)")
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是画布:

SwiftUI-HStack中的选择器

选择器不会调整为屏幕宽度的一半,就像我期望的那样。它们保留其大小,而是拉伸内容视图的宽度,从而扭曲了流程中其他UI元素的宽度(正如我在其他项目中尝试这样做时所发现的那样)。

我知道我可以用它UIViewRepresentable来获得想要的效果,但是鉴于我要使用它的复杂性,SwiftUI会更容易使用。

是将两个选择器放置在内HStack并不能正确调整它们的大小,还是SwiftUI中的选择器只是具有无法更改的固定宽度?


更新资料

使用GeometryReader,我设法更接近于按需调整选择器的大小,但并非始终如此。

旁注:您也可以GeometryReader通过将每个选取器上的框架设置为来获得相同的不完美结果,而无需使用.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)

这是示例代码:

struct ContentView: View {
    @State var selection1: Int = 0
    @State var selection2: Int = 0

    @State var integers: [Int] = [0, 1, 2, 3, 4, 5]

    var body: some View {
        GeometryReader { geometry in
            HStack(spacing: 0) {
                Picker(selection: self.$selection1, label: Text("Numbers")) {
                    ForEach(self.integers) { integer in
                        Text("\(integer)")
                    }
                }
                .frame(maxWidth: geometry.size.width / 2)
                Picker(selection: self.$selection2, label: Text("Numbers")) {
                    ForEach(self.integers) { integer in
                        Text("\(integer)")
                    }
                }
                .frame(maxWidth: geometry.size.width / 2)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是画布:

HStack中带有GeometryReader的选取器

拾取器现在更接近我想要的外观了,但是大小仍然略有偏离,并且它们现在在中间相互重叠。

jus*_*unt 9

从 iOS 15.5(在模拟器上测试)开始,Xcode 13.4 除了添加 .clipped() 之外,您还需要添加以下扩展以防止其他答案的评论中提到的触摸区域重叠问题:

extension UIPickerView {
    open override var intrinsicContentSize: CGSize {
        return CGSize(width: UIView.noIntrinsicMetric , height: 150)
    }
}
Run Code Online (Sandbox Code Playgroud)

只需将其放置在您使用选取器的视图结构之前即可。

资料来源:Apple 论坛上的 TommyL: https://developer.apple.com/forums/thread/687986? answerId=706782022#706782022


kon*_*iki 6

您可以通过添加clipped()修饰符来修复中间的重叠部分。至于宽度,我看到它们完全一样:

在此处输入图片说明

struct ContentView: View {
    @State var selection1: Int = 0
    @State var selection2: Int = 0

    @State var integers: [Int] = [0, 1, 2, 3, 4, 5]

    var body: some View {
        GeometryReader { geometry in
            HStack(spacing: 0) {
                Picker(selection: self.$selection1, label: Text("Numbers")) {
                    ForEach(self.integers) { integer in
                        Text("\(integer)")
                    }
                }
                .frame(maxWidth: geometry.size.width / 2)
                .clipped()
                .border(Color.red)

                Picker(selection: self.$selection2, label: Text("Numbers")) {
                    ForEach(self.integers) { integer in
                        Text("\(integer)")
                    }
                }
                .frame(maxWidth: geometry.size.width / 2)
                .clipped()
                .border(Color.blue)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • UI 显示正确,但手势在 Xcode13 上仍然重叠。你面临这个问题吗? (18认同)