Как скрыть клавиатуру в форме SwiftUI, содержащей средство выбора?

У меня есть SwiftUI Form который содержит Picker, а TextField, а Text:

struct ContentView: View {

    var body: some View {
        Form {
            Section {
                Picker(selection: $selection, label: label) {
                    // Code to populate picker
                }.pickerStyle(SegmentedPickerStyle())
                HStack {
                    TextField(title, text: $text)
                    Text(text)
                }
            }
        }
    }

}

Приведенный выше код приводит к следующему пользовательскому интерфейсу:

Я могу легко выбрать второй элемент в сборщике, как показано ниже:

Ниже вы можете видеть, что я могу начать ввод текста, нажав на TextField:

Чтобы убрать клавиатуру, когда Picker значение обновляется, Binding был добавлен, что можно увидеть в следующем блоке кода:

Picker(selection: Binding(get: {
        // Code to get selected segment
    }, set: { (index) in
        // Code to set selected segment
        self.endEditing()
    }), label: label) {
        // Code to populate picker
    }

Призыв к self.endEditing() предоставляется следующим способом:

func endEditing() {
    sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}

На следующем снимке экрана показано, что выбирается другой сегмент Picker закрывает клавиатуру:

До этого момента все работает как положено. Однако я хотел бы убрать клавиатуру при касании в любом месте за пределамиTextField так как я не могу понять, как закрыть клавиатуру при перетаскивании Formсодержит режим прокрутки.

Я попытался добавить следующую реализацию, чтобы отключить клавиатуру при нажатии на Form:

Form {
    Section {
        // Picker
        HStack {
            // TextField
            // Text
        }
    }
}.onTapGesture {
    self.endEditing()
}

Ниже на следующих двух снимках экрана показано, что TextFieldможет стать первым респондентом и отобразить клавиатуру. Затем клавиатура успешно закрывается при нажатии за пределамиTextField:

Однако клавиатура не исчезнет при попытке выбрать другой сегмент окна `Picker. Фактически, я не могу выбрать другой сегмент даже после того, как клавиатура была отключена. Я предполагаю, что нельзя выбрать другой сегмент, потому что жест касания, прикрепленный к форме, препятствует выбору.

На следующем снимке экрана показан результат попытки выбрать второе значение в Picker пока отображается клавиатура и реализован жест касания:

Что я могу сделать, чтобы разрешить выбор Pickerсегментов, позволяя закрыть клавиатуру при касании за пределами TextField?

2 ответа

import SwiftUI

struct ContentView: View {
    @State private var tipPercentage = 2
    let tipPercentages = [10, 15, 20, 25, 0]
    @State var text = ""

    @State var isEdited = false
    var body: some View {
        Form {
            Section {
                Picker("Tip percentage", selection: $tipPercentage) {
                    ForEach(0 ..< tipPercentages.count) {
                        Text("\(self.tipPercentages[$0])%")
                    }
                }
                .pickerStyle(SegmentedPickerStyle())
                HStack {
                    TextField("Amount", text: $text, onEditingChanged: { isEdited in
                        self.isEdited = isEdited
                    }).keyboardType(.numberPad)
                }
            }
        }.gesture(TapGesture().onEnded({
            UIApplication.shared.windows.first{$0.isKeyWindow }?.endEditing(true)
        }), including: isEdited ? .all : .none)
    }

}

Жест касания формы (чтобы закончить редактирование касанием в любом месте) доступен, только если текстовое поле isEdited == true

однажды isEdited == false, ваш сборщик работает как раньше.

Вы можете поместить весь свой код в VStack{ code }, добавить к нему Spacer() и добавить onTap в этот VStack. Это позволит вам закрыть клавиатуру, щелкнув в любом месте экрана.

Смотрите код ниже:

import SwiftUI

struct ContentView: View {

        @State private var text: String = "Test"

        var body: some View {
            VStack {
                HStack {
                    TextField("Hello World", text: $text)
                    Spacer()
                }
                Spacer()
            }
            .background(Color.red)
            .onTapGesture {
                self.endEditing()
            }
        }

        func endEditing() {
            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        }
    }

Изменение цвета фона HStack или VStack на красный упрощает определение того, где пользователь может щелкнуть, чтобы закрыть.

Скопируйте и вставьте код для готового к запуску примера.

Другие вопросы по тегам