Понимание @Binding в SwiftUI

Я посмотрел несколько видеороликов WWDC и документы Apple о привязке данных, и, согласно моему нынешнему пониманию, @State как делегат свойства обеспечит связующее соединение между представлением и аннотированным свойством, например:

@State var myText: String

var body: some View {
  VStack {
    TextField($myText, placeholder: Text("input"))
    Text(myText)
  }
}

Это будет связывать myTest с содержимым текстового поля, которое я добавил (т.е. одно изменение, другое будет обновляться)

Однако, хотя я знаю, что $myText относится к типу привязки Binding, я заметил, что Binding также является делегатом свойства, и я заметил, что он появляется в некоторых примерах кода от Apple. Я понятия не имею, для чего это используется в качестве делегата свойства. @State уже выполняет связывание, тогда зачем нам @Binding? Apple документы на данный момент отстой по этому поводу.

5 ответов

В соответствии с этим WWDC Talk (поток данных через Swift UI):

https://developer.apple.com/wwdc19/226

@State следует использовать для локальных / частных изменений внутри View, В идеале они были бы частными.

@Binding должны использоваться в подпредставлениях / компонентах многократного использования, когда значение живет outside текущий вид домена.

Вы можете увидеть это в presentation(:_) API-интерфейсы.

Внутри них, вероятно, есть куча состояний, которые говорят SwiftUI как их отображать - но решение о том, должен ли он появиться или нет, зависит от супервизии, поэтому @Binding (isShowing) вам нужно предоставить.

@State - это просто еще один @propertyWrapper, который описывает источник правды.

"... Когда вы используете state, фреймворк выделяет постоянное хранилище для переменной и отслеживает ее как зависимость... вы всегда должны указывать начальное постоянное значение" - WWDC19 Session 226 (07:41)

@ Связывание еще одного @propertyWrapper, который явно зависит от состояния.

"... Используя оболочку свойства Binding, вы определяете явную зависимость от источника правды, не имея его, кроме того, вам не нужно указывать начальное значение, поскольку привязка может быть получена из состояния". - WWDC19, сессия 226 (13:01)

- WWDC19 Сессия 226

  • Если вам нужно простое свойство, которое принадлежит одному представлению, вы должны использовать @State
  • Если вам нужно иметь сложное свойство, которое может принадлежать нескольким представлениям (например, 2-3 представления), вы должны использовать @ObjectBinding
  • Наконец, если вам нужно свойство, которое должно использовать все виды, вы должны использовать @EnvironmentObject.

Binding<T> является делегатом собственности @Binding,

$ myText дает вам Binding<String>,

То, что @State "Обязательная работа", как вы описали это, чтобы дать вам Binding<String> инициализируется с помощью метода получения / установки, который захватывает ссылку на экземпляр State<T>,

В настоящее время TextField изменяет значение myText, вызывая установщик привязки pass-in, который, в свою очередь, вызывает установщик State<T> это на самом деле устанавливает MyText.

Как видите, привязка не обязательно должна иметь фактическое хранимое свойство, она делегируется другому экземпляру, который имеет хранилище, которое в этом случае @State, Отсюда и название.

@State уже выполняет связывание, тогда что нам нужно для @Binding

@State не создает привязку самостоятельно. Оно имеет public var binding: Binding<Value> свойство, которое ( документы):

Используйте привязку, чтобы создать двустороннюю связь между представлением и его базовой моделью.

(в вашем случае между String а также TextField)

Так что binding состояния для привязки значения вперед и назад и @State используя для чтения и изменения значения, и это обеспечивает binding на стоимости, которую он хранит.

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