私は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の機能を取得し、戻るときに私のキーボードを非表示にすることで、これから前進することです
よしみんな
これまでに見てきたことから、キーボードはいくつかのUIの変更を無視するだけですが、かなりエレガントな解決策を見つけました!
ビュー間で渡すことができるブール値「didEnter」のBinding宣言を使用することにより、ユーザーがキーボードでReturnキーを押すと、onCommit()関数がTextFieldビュー内で呼び出されます。そのため、実際にTextFieldビューを同じ外観をシミュレートするテキストを表示するTextビューに切り替えるonCommitのトグルを追加しました。次に、いくつかのタスクが完了した後、もう一度didEnterを切り替えて、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)
}
}
}
}
私の直感は、次のように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)
}
}
}
コーディネーターを使用します。ランドマークの例をご覧ください。チュートリアルで代理人を検索します。外出先で書いているので、リンクを投稿できません。
私はUIImagePickerControllerのためにこれをしました