Có cách nào để gọi hàm khi lựa chọn SwiftUI Picker thay đổi không?


8

Tôi muốn gọi một hàm khi giá trị của selectOption thay đổi. Có cách nào để làm điều này trong SwiftUI tương tự như khi chỉnh sửa TextField không?

Cụ thể, tôi muốn lưu tùy chọn đã chọn khi người dùng thay đổi tùy chọn đã chọn.

Đây là công cụ chọn của tôi:

struct BuilderPicker: View {
    let name: String
    let options: Array<String>
    @State var selectedOption = 0
    var body: some View {
        HStack {
            Text(name)
                .font(.body)
                .padding(.leading, 10)
            Picker(selection: $selectedOption, label: Text(name)) {
                ForEach(0 ..< options.count) {
                    Text(self.options[$0]).tag($0)
                }
            }.pickerStyle(SegmentedPickerStyle())
                .padding(.trailing, 25)
        }.onTapGesture {
            self.selectedOption = self.selectedOption == 0 ? 1 : 0
        }
            .padding(.init(top: 10, leading: 10, bottom: 10, trailing: 0))
            .border(Color.secondary, width: 3)
            .padding(.init(top: 0, leading: 15, bottom: 0, trailing: 15))
            .font(.body)
    }

}

Tôi vẫn chưa quen với SwiftUI và rất thích sự giúp đỡ. Cảm ơn!

Câu trả lời:


10

Nếu giá trị @State sẽ được sử dụng trong Chế độ xem, bạn không cần thêm biến name

  struct BuilderPicker: View {
// let name: String = ""
 let options: Array<String> = ["1", "2","3","4","5"]
 @State var selectedOption = 0
 var body: some View {
    HStack {
        Text(options[selectedOption])
            .font(.body)
            .padding(.leading, 10)
        Picker(selection: $selectedOption, label:    Text(options[selectedOption])) {
            ForEach(0 ..< options.count) {
                Text(self.options[$0]).tag($0)
            }
        }.pickerStyle(SegmentedPickerStyle())
            .padding(.trailing, 25)}
//        }.onTapGesture {
//            self.selectedOption = self.selectedOption == 0 ? 1 : 0
//        }
        .padding(.init(top: 10, leading: 10, bottom: 10, trailing: 0))
        .border(Color.secondary, width: 3)
        .padding(.init(top: 0, leading: 15, bottom: 0, trailing: 15))
        .font(.body)
    }


 }

Nếu bạn cần thao tác tách biệt trên @State, cách đơn giản nhất là thêm một dòng: onReceive () vào dạng xem.

  HStack {
        Text("")
            .font(.body)
            .padding(.leading, 10)
        Picker(selection: $selectedOption, label: Text("")) {
            ForEach(0 ..< options.count) {
                Text(self.options[$0]).tag($0)
            }
        }.pickerStyle(SegmentedPickerStyle())
            .padding(.trailing, 25)}
  //        }.onTapGesture {
 //            self.selectedOption = self.selectedOption == 0 ? 1 : 0
 //        }
        .padding(.init(top: 10, leading: 10, bottom: 10, trailing: 0))
        .border(Color.secondary, width: 3)
        .padding(.init(top: 0, leading: 15, bottom: 0, trailing: 15))
        .font(.body)
        .onReceive([self.selectedOption].publisher.first()) { (value) in
            print(value)
    }

Lý do did set không hoạt động với bạn là vì bạn đã nhận xét onTapGesture. Tôi đang thử ý tưởng của bạn bây giờ.
Mặt trận Eli

Không sử dụng cử chỉ bổ sung nếu mọi thứ trên @State var được tích hợp.
E.Coms

Điều này hoạt động, nhưng nó cảm thấy như nên có một cách tốt hơn để làm điều này. Cảm ơn!
Mặt trận Eli

5
Điều này hoạt động, nhưng "[self.selectedOption] .publisher.first ()" w00t? :)
sabiland

2
[self.selectedOption].publisher.first()API công cộng? Nó không giống như API công khai, nhưng trời ơi nó hoạt động.
Iron John Bonney
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.