将按钮添加到选择器标签

Add button to picker label

我想给 swiftui picker 的标签添加一个按钮。
但是这个按钮是不可点击的。
当我点击按钮时,选择器被点击。
如何让选取器只在选定值的区域进行点击?
按钮需要他点击吗?

import SwiftUI


enum Animal: String, CaseIterable, Identifiable {
    case dog
    case cat
    case bird
    var id: String { self.rawValue }
}

struct ContentView: View {
    @State private var selectedAnimal = Animal.dog
    
    var body: some View {
        Form {
            Group {

                Section(header: Text("Animales")) {
                    VStack{

                        Picker(
                            selection: $selectedAnimal,
                            content: {
                                ForEach(Animal.allCases, id:\.self) {
                                    Text([=10=].rawValue)
                                }},
                            label: {
                                HStack {
                                    Text ("Chose Animale")
                                    Spacer ()
                                    Button (
                                        action: {
                                            print ("clicked")
                                        },
                                        label: {
                                            Image(systemName: "arrow.clockwise")
                                        })
                                    
                                    Spacer ()
  
                                }
                            }
                        )
                    }
                }
            }
        }
    }
}

要解决这个问题,我们需要将选择器和按钮分开,并阻止表单在行内跟踪点击(默认跟踪整行)。

首先将按钮移出选择器并将所有内容放入 HStack,其次我们需要一些技巧,例如标签上的 tapGesture 和按钮的非默认按钮样式(为简单起见,我使用了原始按钮样式,但最好用适当的高亮等创建自定义)

这是一个简化的更新和测试代码 (Xcode 13 / iOS 15):

var body: some View {
    Form {
        Group {
            Section(header: Text("Animales")) {
                HStack{
                    HStack {
                        Text ("Chose Animale")
                        Spacer ()
                    }
                    .contentShape(Rectangle())
                    .onTapGesture {
                       // just blocker for label click
                    }
                    .overlay(
                        Button (
                            action: {
                                print ("clicked")
                            },
                            label: {
                                Image(systemName: "arrow.clockwise").foregroundColor(.blue)
                            })
                            .buttonStyle(PlainButtonStyle())   // << needed custom !!
                    )
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .layoutPriority(1)     // << to cover much area
                    //.border(Color.red)      // << for testing area

                    Picker("",
                             selection: $selectedAnimal,
                             content: {
                        ForEach(Animal.allCases, id:\.self) {
                            Text([=10=].rawValue)
                        }}
                    )
                        .labelsHidden()   // << hide own label
                        .fixedSize()      // << limit size !!
                }
                .listRowInsets(EdgeInsets()) // << consume row space !!
            }
        }
    }
}