Я пытаюсь захватить текст, введенный в TextEditor, сохранить его в переменной и обновить то, что отображается в самом TextEditor. Я использую .onChange() для запуска и захвата того, что набирается, сохраняю его в переменной и изменяю текущий отображаемый текст. Но проблема в том, что .onChange() вызывается дважды: во-первых, когда я набираю текст внутри TextEditor; и во-вторых, когда я пытаюсь установить другой символ для самого представления.
struct ChatView: View {
@State var chatTextInput: String = ""
@State var oldChatValue: String = ""
@State var newChatValue: String = ""
var body: some View {
VStack {
TextEditor(text: $chatTextInput)
.onChange(of: chatTextInput) { newValue in
oldChatValue += "a"
newChatValue += newValue.last.map{String($0)}!
chatTextInput = oldChatValue
}
}
}
}
Например, если я наберу qwerty, newChatValue будет напечатан как Каваиратая, а chatTextInput получит ааааааааааааааа.
Любые подсказки о том, как предотвратить запуск .onChange во второй раз, когда я устанавливаю новый символ для текста TextEditor?
Большое спасибо!
Или... вы хотите, чтобы "а" показывалось независимо от того, что набрано? Так, например, когда вы вводите «qwerty», вы хотите, чтобы текстовый редактор отображал «aaaaaa», а newChatValue должен содержать «qwerty»?
@DonMag Да, извините, если я недостаточно ясно выразился. То, что я пытаюсь, это именно то, что вы сказали. Я хочу, чтобы «а» заменило все, что пользователь вводит в TextEditor. И newChatValue должен хранить то, что было напечатано.





Ваша проблема просто в том, что .onChange(of:) не отвечает на TextEditor, а отвечает на переменную, в данном случае chatTextInput. Поскольку chatTextInput привязан к TextEditor, когда вы вводите букву, chatTextInput обновляется и запускается .onChange(of:). Однако, как часть .onChange(of:) выполнения, вы изменяете chatTextInput, который вызывает .onChange(of:) again. You would have an infinite loop, except that .onChange(of:)` на этом заканчивается. Если кто-то может объяснить это, я хотел бы услышать это.
Однако исправление состоит в том, чтобы просто поставить флаг в .onChange(of:), чтобы устанавливать переменные только через раз, например:
struct ChatView: View {
@State var chatTextInput: String = ""
@State var oldChatValue: String = ""
@State var newChatValue: String = ""
@State var textEntryFlag = true
var body: some View {
VStack {
TextEditor(text: $chatTextInput)
.onChange(of: chatTextInput) { newValue in
if textEntryFlag {
oldChatValue += "a"
newChatValue += newValue.last.map{String($0)}!
chatTextInput = oldChatValue
}
textEntryFlag.toggle()
}
}
}
}
Спасибо, это было очень просто и помогло!! Знаете ли вы, есть ли какой-либо другой способ решить эту проблему без использования .onChange(), который действует как ответчик непосредственно в TextEditor?
Для TextEditor больше ничего нет. Для TextField у вас есть .onSubmit(of:), но в настоящее время его не существует для TextEditor.
Это я и подозревал. В любом случае, еще раз спасибо за вашу помощь!
Возможно, вам лучше объяснить, что именно вы хотите сделать... Вы пытаетесь вставить «а» между каждым введенным символом?