Быстрое обновление привязки сохраненное значение программно из расширения представления

#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. Достаточно хороший ответ для меня! Спасибо!