TGViewer
Мобильный трудоголик Мобильный трудоголик @hardworkerit · 1.65K subscribers
Post #399 1.23K
🔢 Жизненный цикл SwiftUI View: когда onAppear вызывается не так, как ожидали.

На первый взгляд, onAppear кажется простым и понятным: показалась вью - сработало, скрылась - сработало onDisappear. Но на практике все сложнее. В зависимости от того, где находится вью - в TabView, NavigationStack или List - поведение может кардинально отличаться. И если не понимать этих нюансов, можно нарваться на баги, которые трудно воспроизвести.


Две разные системы:

Чтобы понять, что происходит, нужно разделить два понятия: время жизни узла (node lifetime) и видимость на экране (visibility). Узел живет, пока существует идентичность вью. К узлу привязаны @State и @StateObject. А видимость - это то, видит ли пользователь вью сейчас. onAppear и onDisappear реагируют именно на видимость, а не на создание или уничтожение узла.

В простых случаях эти две шкалы совпадают. Но в сложных контейнерах - расходятся.


TabView - узлы живут, видимость меняется:

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

Нюанс: на iOS 17 TabView создавал все вкладки сразу при запуске. На iOS 18+ - только при первом открытии. Один и тот же код может вести себя по-разному на разных версиях.


NavigationStack - при возврате узел уничтожается:

В навигационном стеке при возврате назад (pop) узел детальной вью уничтожается, а @State сбрасывается. При повторном переходе создается новый узел. В отличие от TabView, здесь данные не сохраняются между показами.


List и LazyVStack - узлы создаются и уничтожаются при скролле:

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


Главное правило - body выполняется до onAppear:

body вычисляется до того, как сработает onAppear или .task. Нельзя полагаться на то, что в onAppear данные подгрузятся до первого вызова body. Нужно всегда предусматривать начальное состояние.


🔗 Читать подробнее


💡 Вывод:

onAppear в SwiftUI - это не «вью создана», а «вью стала видимой». Время жизни узла и видимость - это две независимые шкалы. Понимание этого спасает от багов, когда @State вдруг не сбрасывается или, наоборот, сбрасывается не вовремя. Разные контейнеры ведут себя по-разному и это нужно тестировать, а не гадать.


Подписаться на канал:
➡️ Telegram | Max

Закрытый канал:
🚀 Мобильный трудоголик PRO
  • 👍 13
  • ❤ 4
  • 🔥 1
  • 🙏 1
  • 🤝 1
More from @hardworkerit
  1. Oct 1, 2026🔢 Работа с Picture-in-Picture в iOS. Picture-in-Picture - системная функция iOS, которая…
  2. Sep 29, 2026🔢 Управление тулбарами на iPhone Duo. На iPhone Duo элементы управления навигацией, дейст…
  3. Sep 27, 2026🔢 Новые возможности Hashable в Swift 6.4 В Swift 6.4 добавили Hashable для нескольких тип…
  4. Sep 25, 2026🔢 Приватные свойства больше не ломают memberwise инициализатор в Swift 6.4 Swift автомати…
  5. Sep 24, 2026👨‍💻 Почему разработчики ненавидят своих менеджеров. Всем привет! Сегодня хочу разобрать…
  6. Sep 22, 2026🔢 Релиз Swift 6.4: главные изменения для разработчиков. Swift 6.4 вышел. Это обновление п…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →