SwiftUI передает сохраненное значение родительскому представлению - PullRequest
1 голос
/ 11 июля 2020

Я новичок в SwiftUI. Я пытаюсь найти лучший способ передать данные из дочернего представления в родительский?

Спасибо за помощь, я пришел из фона Javascript (React), поэтому это немного отличается для меня

Мой дочерний вид работает так: пользователь нажимает на изображение, чтобы выбрать это изображение.

У меня есть привязка @State, которая сохраняет imgUrl, который является строкой ссылаясь на имя в Assets.

Я просто не уверен, как лучше всего передать это значение родительскому компоненту.

Вот дочернее представление (imageSelector)

struct ImageSelector: View {
@State private var windowImgs = ["1", "2", "3","4","5","6","7","8","9","10","11","12","13", "14","15","16","17","18"]

@State private var imgPicked = ""


var body: some View{
    ScrollView(Axis.Set.horizontal, showsIndicators: true){
        HStack{
            ForEach(0..<18){num in
                Button(action:{
                    self.imgPicked = self.windowImgs[num]
                    print(self.imgPicked)
                }){
                    Image("\(self.windowImgs[num])")
                        .renderingMode(.original)
                        .resizable()
                        .cornerRadius(4)
                        .frame(width: 100, height: 100)
                }
            }
        }
    }
}

}

Вот родительское представление (AddCounterForm)

struct AddCounterForm: View {
@Environment(\.presentationMode) var presentationMode
@State private var pickedImg: String = "defaultImg"
@State private var price: String = "0.0"
@State private var qty: String = "0"
var body: some View {
    VStack (spacing: 40){
        HStack {
            Button("Cancel"){
                self.presentationMode.wrappedValue.dismiss()
            }
            .foregroundColor(.red)
            Spacer()
            Button("Save"){
                
            }
        }
        HStack {
            VStack (spacing: 20){
                TextField("Window type", text: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Value@*/.constant("")/*@END_MENU_TOKEN@*/)
                TextField("Window location", text: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Value@*/.constant("")/*@END_MENU_TOKEN@*/)
            }
            .textFieldStyle(RoundedBorderTextFieldStyle())
            Image(pickedImg)
                .resizable()
                .cornerRadius(4)
                .frame(width: 90, height: 90)
                .padding(.leading)
        }
        
        HStack {
            Text("Price")
            TextField("", text:$price)
                .frame(width: 70)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.numberPad)
            Spacer()
            Text("Qty")
            TextField("", text:$qty)
                .frame(width: 70)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.numberPad)
        }
        VStack {
            Text("Select an image")
                .foregroundColor(.blue)
            ImageSelector()
                .padding(.bottom)
            
            Button("Use your own image"){
                //method
            }
            .frame(width: 180, height: 40)
            .background(Color.blue)
            .clipShape(Capsule())
            .foregroundColor(.white)
            .padding(.top)
        }
        
    }
    .padding()
}

}

Решение для предварительного просмотра, спасибо за помощь от @Asperi & @ neverwinterMoon

struct ImageSelector_Previews: PreviewProvider {
static var previews: some View {
    PreviewWrapper()
}

}

struct PreviewWrapper: View {@State (initialValue: "") var imgPicked: String

var body: some View {
    ImageSelector(imgPicked: $imgPicked)
}

}

1 Ответ

1 голос
/ 11 июля 2020

В этом случае Binding является наиболее подходящим

struct ImageSelector: View {
   @Binding var imgPicked: String

и используйте

ImageSelector(imgPicked: $pickedImg)
    .padding(.bottom)
...