С
iOS 18 и
macOS 15 UIKit получил скрытую фичу, которая меняет правила игры - автоматическое отслеживание изменений данных через
@Observable. Больше не нужны ручные вызовы
setNeedsLayout() - интерфейс теперь обновляется сам!
Как это работает:
Помечаем модель макросом @Observable:
import Observation
@Observable
class User {
var name = "Иван"
var unreadMessages = 0
}
Читаем данные в стандартных методах ViewController:
class ProfileVC: UIViewController {
let user = User()
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
// UIKit автоматически отследит эти изменения
nameLabel.text = user.name
messagesCountLabel.text = "\(user.unreadMessages)"
}
}
Изменяем данные - интерфейс обновится автоматически:
@objc func buttonDidTap() {
// Значение messagesCountLabel обновится автоматически
user.unreadMessages += 1
}
Включаем отслеживание @Observable в Info.plist:
UIObservationTrackingEnabled
В
iOS 26 это работает из коробки без настройки.
Важные нюансы:
- Автоматическое отслеживание изменений работает в viewWillLayoutSubviews(), layoutSubviews() и новом методе updateProperties(), который вызывается перед layoutSubviews для оптимизации.
- Обновление интерфейса после обновления данных возможно только в main thread.
- Важно не забывать про retain cycles, при работе с @Observable.
- Рекомендуется избегать обновление данных без необходимости, так как частое обновление интерфейса может сказаться на производительности приложения.
Вывод:
Теперь
UIKit умеет так же удобно обновлять интерфейс, как
SwiftUI. Главное - правильно использовать
@Observable и не забывать про потокобезопасность.