Понимание @Binding в SwiftUI - PullRequest
5 голосов
/ 07 июня 2019

Я смотрел некоторые видео 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 ]

6 голосов
/ 07 июня 2019

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

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

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

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

Вы можете увидеть его в presentation(:_)API.

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

4 голосов
/ 07 июня 2019

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

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

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

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

enter image description here - Сессия WWDC19 226

1 голос
/ 26 июня 2019

Binding<T> является делегатом свойства @Binding.

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

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

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

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

1 голос
/ 07 июня 2019

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

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

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

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

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

0 голосов
/ 26 июня 2019
  • Если вам нужно простое свойство, которое принадлежит одному представлению, вы должны использовать @ State
  • Если вам нужно иметь сложное свойство, которое может принадлежать нескольким представлениям (например,2-3 представления) вы должны использовать @ ObjectBinding
  • Наконец, если вам нужно свойство, которое должно использовать все виды представлений, вы должны использовать @EnvironmentObject.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...