Что делает ключевое слово SwiftUI `@ State`? - PullRequest
19 голосов
/ 04 июня 2019

Учебное пособие SwiftUI использует ключевое слово @State для обозначения изменяемого состояния пользовательского интерфейса:

@State var showFavoritesOnly = false

Это сводка предлагает:

Состояние - это значение или набор значений, которые могут изменяться с течением времени и влиять на поведение, содержимое или макет представления.Вы используете свойство с атрибутом @State для добавления состояния в представление.

  • Что именно означает ключевое слово?
  • Как происходит изменение переменной @Stateзаставить пересчитать представление?
  • Как другие переменные неизменяемы в body getter?

Ответы [ 5 ]

20 голосов
/ 04 июня 2019

Ключевое слово @State - это @propertyWrapper, функция, недавно представленная в Swift 5.1. Как объяснено в соответствующем предложении , это своего рода оболочка значений, избегающая стандартного кода.


Sidenote: @propertyWrapper ранее назывался @propertyDelegate, но с тех пор он изменился. См. этот пост для получения дополнительной информации.


Официальная документация @ 1017 *1018* содержит следующее:

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

Экземпляр State не является самим значением; это средство чтение и изменение значения . Чтобы получить доступ к основной ценности государства, используйте свойство value.

Поэтому, когда вы инициализируете свойство, помеченное @State, вы фактически не создаете свою собственную переменную, а скорее предлагаете SwiftUI создать "что-то" в фоновом режиме, в котором хранится то, что вы установили и контролирует это отныне! Ваш @State var просто действует как делегат для доступа к этой оболочке .

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

2 голосов
/ 05 июня 2019

Это хорошо объяснено на примере видео WWDC - сессия 204 (начинается в 16:00, цитата начинается в 20:15)

Одним из специальных свойств переменных @State является то, что SwiftUI может наблюдать, когда они читаются и пишутся. Поскольку SwiftUI знает, что zoomed было прочитано в body, он знает, что от него зависит представление представления. Это означает, что когда переменная изменится, каркас снова запросит body, используя новое значение @State.

@State в качестве Оболочки свойств также разработан и обоснован в Потоке данных через Swift UI (5:38) в WWDC vid. Показано, как это решает проблему, когда нам нужно непостоянное значение в неизменяемом (struct) View.

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

Если вы нажмете на @State, вы увидите, что у него есть несколько геттеров. Один с Value другой с Binding<Value>. SwiftUI, кажется, сильно зависит от реактивного программирования (и их новой Combine инфраструктуры, и, поскольку мы не можем увидеть полную реализацию этих оболочек, я ожидаю, что значения, которые хранятся в оболочках @State свойств, управляются CurrentValueSubject из Combine. Как следует из названия, по сути, в нем хранится текущее значение, которое затем можно использовать в качестве привязываемого свойства с использованием синтаксиса $.

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

Позвольте мне добавить еще кое-что, если вы знаете React Native.

Свойство @State очень похоже на объект this.state в React Native.

Например:

struct Foobar: some View {
    @State var username = ""
}
class Foobar extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      username: '',
    };
  }
}

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

0 голосов
/ 04 июня 2019

Если вы знаете о C # и разработке Windows.@State аналогично, если не совпадает с x:Bind или Binding .. В коллекции оно аналогично, если не совпадает с ObservableCollection.

Как сказал fredpi, SwiftUI перечисляет обновления дляпеременные с делегатом свойства @State.

...