web-dev-qa-db-fra.com

Swiftui avec fonctions déléguées pour mkmapview et uitextfield

Je m'entraîne et je lis sur SwiftUI et je commence par créer une application simple où vous pouvez taper un emplacement dans un TextField Vue depuis swiftUI puis sur Entrée mkmapview dans SwiftUI ira à nouveau à cet emplacement que j'ai recherché. Je ne peux pas, pour la vie de moi, comprendre comment obtenir cette fonctionnalité avec mon mkmapview.

De plus, je ne peux même pas trouver un moyen de supprimer le clavier de Textfield sans faire une navigation ou rendre une nouvelle vue ou supprimer une vue.

Quelqu'un peut-il me montrer comment je peux retirer mon clavier? J'ai l'habitude de resignFirstResponder() ou didFinishEditing().
De plus, quelqu'un a-t-il des suggestions sur la façon d'affecter des fonctionnalités au MKMapView de swiftUI ou est-ce que je regarde tout cela de travers?

Je pensais que dans le gestionnaire onCommit de Textfield, j'appellerais une fonction qui pourrait transmettre les données nécessaires à MapView et gérer cela, mais je n'ai pas été en mesure de trouver un bon moyen de le faire.

struct MainView : View {

    @State var text: String = ""

    var body: some View {
        VStack {
            MapView()
                .frame(height: UIScreen.main.bounds.height)
                .offset(y: 50)
                //.edgesIgnoringSafeArea(.top)

            SearchField(text: "")
                .offset(y: -(UIScreen.main.bounds.height) + 60)
                .padding()
        }
    }
}
struct MapView : UIViewRepresentable {
    func makeUIView(context: Context) -> MKMapView {
        MKMapView(frame: .zero)
    }

    func updateUIView(_ view: MKMapView, context: Context) {
        let coordinate = CLLocationCoordinate2D(
            latitude: 34.011286, longitude: -116.166868)
        let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
        let region = MKCoordinateRegion(center: coordinate, span: span)
        view.setRegion(region, animated: true)
    }
}
struct SearchField : View {
    @State var text: String
    @State var showDetails: Bool = false

    var body: some View {
        VStack {
            RoundedRectangle(cornerRadius: 30).frame(width: 300, height: 40)
                .foregroundColor(.white)
                .offset(y: 55)
            TextField($text, placeholder: Text("City, State, or Address"), onEditingChanged: { body in
                print(body)

            }, onCommit: {
                print(self.text)
            })
                .padding()
                .offset(x: 50)
        }
    }
}

* Modifier la note: mon code ci-dessus fonctionne, il créera une vue de carte en plein écran avec un champ de texte dessus et le champ de texte prendra du texte et mettra à jour son état. Ma question consiste à aller de l'avant avec l'obtention de fonctionnalités dans mapview et à masquer mon fichu clavier en retour

6
nikoclicks

D'accord les gars,

Donc, d'après ce que j'ai vu jusqu'à présent, les claviers ne seront rejetés que sur certains changements d'interface utilisateur, mais j'ai trouvé une solution assez élégante!

En utilisant une déclaration de liaison pour un "didEnter" booléen que je peux passer entre les vues, lorsque l'utilisateur revient sur le clavier, la fonction onCommit () est appelée dans la vue TextField. J'ai donc ajouté une bascule pour onCommit qui bascule réellement ma vue TextField vers une vue Text qui affiche le texte simulant le même aspect, puis une fois la tâche terminée, je bascule à nouveau didEnter qui revient au TextField.

Se sent toujours comme une solution de contournement, mais fonctionne pour l'instant.

struct InputView : View {
    @Binding var text:          String
    @Binding var didEnter:      Bool
    @State   var searchType:    SearchType

    var body: some View {
        ZStack{
            RoundedRectangle(cornerRadius: 15).frame(width: 310, height: 100)
                .foregroundColor(.secondary)
                .offset(y: -20)
            ZStack{
                RoundedRectangle(cornerRadius: 30).frame(width: 290, height: 40)
                    .foregroundColor(.white)
                if(!didEnter){
                    TextField($text, placeholder: Text("City, State, Address")) {
                        print(self.text)
                        self.didEnter.toggle()
                    }
                        .frame(width: 220, height: 40, alignment: .leading)
                        .offset(x: -20)
                }
                else{
                    Text(self.text).frame(width: 220, height: 40, alignment: .leading)
                        .offset(x: -20)
                }
                Text("Select Location:").bold().fontWeight(.medium)
                    .offset(y: -40)
                    .foregroundColor(.white)
            }
        }
    }
}
0
nikoclicks

Mon intuition est que vous devez passer la liaison dans le SearchField comme ceci:

struct MainView : View {

    @State var text: String = ""

    var body: some View {
        VStack {
            MapView()
                .frame(height: UIScreen.main.bounds.height)
                .offset(y: 50)
            //.edgesIgnoringSafeArea(.top)

            SearchField(text: $text)
                .offset(y: -(UIScreen.main.bounds.height) + 60)
                .padding()
        }
    }
}

struct MapView : UIViewRepresentable {
    func makeUIView(context: Context) -> MKMapView {
        MKMapView(frame: .zero)
    }

    func updateUIView(_ view: MKMapView, context: Context) {
        let coordinate = CLLocationCoordinate2D(
            latitude: 34.011286, longitude: -116.166868)
        let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)
        let region = MKCoordinateRegion(center: coordinate, span: span)
        view.setRegion(region, animated: true)
    }
}

struct SearchField : View {
    @State var text: Binding<String>

    var body: some View {
        VStack {
            RoundedRectangle(cornerRadius: 30).frame(width: 300, height: 40)
                .foregroundColor(.white)
                .offset(y: 55)
            TextField(text, placeholder: Text("City, State, or Address"), onEditingChanged: { body in
                print(self.text)

            }, onCommit: {
                print(self.text)
            })
                .padding()
                .offset(x: 50)
        }
    }
}
0
Andrew Ebling

Utilisez un coordinateur. Découvrez leur exemple de repères. Recherchez délégué dans le didacticiel. J'écris en déplacement, je ne peux donc pas publier le lien.

Je l'ai fait pour UIImagePickerController

0
alexbuga