web-dev-qa-db-ja.com

mkmapviewおよびuitextfieldのデリゲート関数を備えたSwiftui

私はSwiftUIを練習して読んでいます。TextFieldからのswiftUIビューに場所を入力してEnterキーを押す簡単なアプリを作成するところから始めます。 mkmapview内のSwiftUIは、検索した場所に再び移動します。私の人生では、この機能をmkmapviewでセットアップする方法を理解できていないようです。

さらに、ナビゲーションを実行したり、新しいビューをレンダリングしたり、ビューを削除したりせずに、キーボードをTextfieldから閉じる方法すら見つけられません。

キーボードを閉じる方法を誰かに教えてもらえますか?私はresignFirstResponder()またはdidFinishEditing()に慣れています。
また、MKMapViewからswiftUIに機能を割り当てる方法について何か提案はありますか、またはこれをすべて間違っていると思いますか?

テキストフィールドのonCommitハンドラーで、必要なデータをMapViewに渡して処理できる関数を呼び出すと考えましたが、それを行うための適切な方法を見つけることができませんでした。

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)
        }
    }
}

*編集注意:上記の私のコードは機能し、テキストフィールドを含む全画面のマップビューを構築し、テキストフィールドはテキストを受け取り、その状態を更新します。私の質問は、mapviewの機能を取得し、戻るときに私のキーボードを非表示にすることで、これから前進することです

6
nikoclicks

よしみんな

これまでに見てきたことから、キーボードはいくつかのUIの変更を無視するだけですが、かなりエレガントな解決策を見つけました!

ビュー間で渡すことができるブール値「didEnter」のBinding宣言を使用することにより、ユーザーがキーボードでReturnキーを押すと、onCommit()関数がTextFieldビュー内で呼び出されます。そのため、実際にTextFieldビューを同じ外観をシミュレートするテキストを表示するTextビューに切り替えるonCommitのトグルを追加しました。次に、いくつかのタスクが完了した後、もう一度did​​Enterを切り替えて、TextFieldに切り替えます。

まだ回避策のように感じますが、今のところ機能します。

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

私の直感は、次のようにSearchFieldにバインディングを渡す必要があることです。

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

コーディネーターを使用します。ランドマークの例をご覧ください。チュートリアルで代理人を検索します。外出先で書いているので、リンクを投稿できません。

私はUIImagePickerControllerのためにこれをしました

0
alexbuga