如何让 SwiftUI Picker 占用 HStack 中的整个可用空间?

How to make SwiftUI Picker take the whole free space in HStack?

提问人:Kaloyan Stefanov 提问时间:9/16/2023 更新时间:9/16/2023 访问量:71

问:

我需要创建一个输入字段,在其中使用标准的 SwiftUI Picker。这是我的观点:

struct CustomPickerRowView<Content:View>: View {
    
    let icon: String
    
    let picker: () -> Content
    
    var body: some View {
        HStack {
            ZStack {
                K.Gradients.mainGradient
                
                Image(systemName: icon)
                    .foregroundStyle(.white.opacity(0.8))
                    .font(.title3)
                    .fontWeight(.bold)
            }
            .frame(width: 45, height: 45)
            
            picker()
                .offset(x: -10)
            
            Spacer()
        }
        .frame(height: 45)
        .background(.textfieldAppearance)
        .clipShape(RoundedRectangle(cornerRadius: 12))
        .shadow(color: .textfieldBg.opacity(0.3), radius: 3, x: 2, y: 2)
    }
}

我是这样使用它的:

CustomPickerRowView(icon: "figure.run") {
    Picker("", selection: $activityLevel) {
        ForEach(ActivityLevel.allCases, id: \.self) { level in
            Text("\(level.rawValue)".camelCaseToWords())
        }
    }
    .tint(activityLevel == .SelectActivity ? .textGray : .text)
}

我需要让这个选择器占用全部可用空间,并且在我按下它的任何位置都可以单击。

我试图用maxWidth修饰符让它占用全部可用空间:

.frame(maxWidth: .infinity)

但可点击区域未覆盖整个选取器宽度

iOS SwiftUI swiftUI 选择器

评论


答:

0赞 Benzy Neez 9/16/2023 #1

我发现,如果你在选择器标签上填充空格,那么就会使用所有可用的空间,并且在整个宽度上点击是很敏感的。幸运的是,添加比需要更多的填充似乎没有任何负面影响,因此您可以添加大量填充以确保填充整个宽度。具体而言,您不会看到任何省略号出现。Picker

我认为您正在尝试使用来删除 .我建议供应给实现这一目标。您可能也不再需要这些了。.offsetHStackspacing: 0HStackSpacer

以下是应用更新(以及即兴设置的差距)的示例:

enum ActivityLevel: String, CaseIterable {
    case selectActivity = "Select Activity"
    case walk = "Walk"
    case run = "Run"
}

struct CustomPickerRowView<Content:View>: View {

    let icon: String
    let picker: () -> Content

    var body: some View {
        HStack(spacing: 0) {
            ZStack {
//                K.Gradients.mainGradient
                LinearGradient(
                    colors: [Color(white: 0.8), Color(white: 0.3)],
                    startPoint: .top,
                    endPoint: .bottom
                )
                Image(systemName: "figure.walk") // icon
                    .foregroundStyle(.white.opacity(0.8))
                    .font(.title3)
                    .fontWeight(.bold)
            }
            .frame(width: 45, height: 45)

            picker()

            Spacer()
        }
        .frame(height: 45)
        .background(Color(white: 0.9)) // .textfieldAppearance
        .clipShape(RoundedRectangle(cornerRadius: 12))
        .shadow(color: .gray, radius: 3, x: 2, y: 2) // .textfieldBg.opacity(0.3)
    }
}

struct ContentView: View {
    @State private var activityLevel = ActivityLevel.selectActivity
    let padding = String(repeating: " ", count: 1000)

    var body: some View {
        CustomPickerRowView(icon: "figure.run") {
            Picker("", selection: $activityLevel) {
                ForEach(ActivityLevel.allCases, id: \.self) { level in
                    Text("\(level.rawValue)" + padding).tag(level)
                }
            }
            .tint(.primary)
//            .tint(activityLevel == .selectActivity ? .textGray : .text)
        }
    }
}

ActivityPicker