О чем эта статья

В этой статье мы создадим протокол Updater. Программы обновления будут применять набор правил, которые диктуют, когда представление должно обновляться. В частности, мы сделаем три отдельных средства обновления для разных ситуаций:

  1. Updaters.Nonduplicate - обновляется при нарушении равенства
  2. Updaters.True - обновляется, когда его значение истинно.
  3. Updaters.Event - обновляется при получении значения от издателя.

Апдейтеры будут назначаться так же, как и ViewModifiers.

view.modifier(Updaters.Nonduplicate(equatable))
view.modifier(Updaters.True(boolean))
view.modifier(Updaters.Event(publisher))

Как обновляются просмотры

Представления распространяют изменения путем пересчета своего тела, которое, в свою очередь, сообщает каждому подпредставлению пересчитать свое тело и т. Д., И т. Д. Представления, как правило, дешевы в вычислительном отношении, поэтому этот процесс обычно происходит мгновенно. Однако представьте, что у вас есть представление, требующее больших вычислительных ресурсов, и вы хотите вручную контролировать, когда оно обновляется, тогда такое поведение больше не подходит.

SwiftUI поставляется с EquatableView. Он оборачивает другое представление, которое соответствует equatable, и пересчитывает его тело только тогда, когда оно получает представление, нарушающее равенство. Это позволяет нам отменять обновления либо потому, что мы считаем их ненужными, либо потому, что нам нужно особое поведение.

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

Updater

Хотя наивно привести свои взгляды в соответствие с Equatable можно, это не всегда уместно. Представьте, что вы хотите обновить представление только в ответ на опубликованное событие. Должно ли представление знать о событии? Возможно нет. Обычно лучше не знать о своих взглядах.

Updater помогает нам разделить проблемы. Вместо того, чтобы согласовывать представления с Equatable, средство обновления помещает его в другое представление, которое соответствует Equatable и содержит всю необходимую информацию для обеспечения его поведения при обновлении. Каждое средство обновления будет входить в список под названием Updaters, аналогично тому, как Combine работает с Publishers.

Стоит отметить, что Updater не соответствует ViewModifier. Причина проста: ViewModifier в этой ситуации не работает (я пробовал).

1. Недубликатность

Наша первая программа обновления берет значение и сравнивает его с предыдущим значением. Он обновляет свое представление только тогда, когда равенство нарушено.

2. Верно

Наша вторая программа обновления принимает логическое значение и обновляет свое представление только тогда, когда логическое значение равно true. Он делает это, оценивая свое последнее (rhs) значение при проверке равенства.

3. Событие

Наш третий апдейтер немного интереснее. Он принимает издателя и обновляет представление только тогда, когда получает значение от издателя. Это делается в два этапа: сначала он блокирует все обновления при проверке равенства, затем сообщает SwiftUI, что его состояние изменилось всякий раз, когда издатель выдает значение.

Результат

С помощью всего нескольких строк кода мы сделали возможным и даже простым управлять поведением обновления вашего представления в широком диапазоне сценариев, не внося никаких изменений в само представление.

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

Ссылки

Пакет / исходный код: https://github.com/oscbys/OBEUpdaters