#ios #swift #swiftui #binding
Вопрос:
Поэтому моя цель состоит в том , чтобы иметь более удобный метод добавления текстового значения-заполнителя в SwiftUI TextEditor
, поскольку его, похоже, нет. Подход, который я пытаюсь применить, обнаружил кое-что, чего я действительно не понимаю Binding<>
в отношении завернутых типов. (Может быть, это красный флаг, что я делаю что-то не рекомендованное?)
В любом случае, перейдем к моему вопросу: можем ли мы программно обновить базовые значения на Binding
s? Если я приму какое Binding<String>
-то значение, могу ли я обновить его из своего метода здесь? Если да, будет ли создатель ссылаться на обновленное значение @State
? В приведенном ниже примере мое значение заполнителя помещается в текст, который я пытаюсь ввести, когда вы нажимаете на него, и даже не пытается повторить, если я его удалю.
Импортировал этот код из других сообщений, которые я нашел некоторое время назад, чтобы он отображал заполнитель, если тело пустое.
import Foundation
import SwiftUI
struct TextEditorViewThing: View {
@State private var noteText = ""
var body: some View {
VStack{
TextEditor(text: $noteText)
.textPlaceholder(placeholder: "PLACEHOLDER", text: $noteText)
.padding()
}
}
}
extension TextEditor {
@ViewBuilder func textPlaceholder(placeholder: String, text: Binding<String>) -> some View {
self.onAppear {
// remove the placeholder text when keyboard appears
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { (noti) in
withAnimation {
if text.wrappedValue == placeholder {
text.wrappedValue = placeholder
}
}
}
// put back the placeholder text if the user dismisses the keyboard without adding any text
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { (noti) in
withAnimation {
if text.wrappedValue == "" {
text.wrappedValue = placeholder
}
}
}
}
}
}
Ответ №1:
Настройте эту настройку в соответствии с вашими требованиями:
struct ContentView: View {
@State private var text: String = ""
var body: some View {
VStack {
ZStack(alignment: .leading) {
if self.text.isEmpty {
VStack {
Text("Placeholder Text")
.multilineTextAlignment(.leading)
.padding(.leading, 25)
.padding(.top, 8)
.opacity(0.5)
Spacer()
}
}
TextEditor(text: $text)
.padding(.leading, 20)
.opacity(self.text.isEmpty ? 0.5 : 1)
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/2)
.overlay(
Rectangle().stroke()
.foregroundColor(Color.black)
.padding(.horizontal, 15)
)
}
}
}
Комментарии:
1. Достаточно хороший ответ для меня! Спасибо!