Разработка
Производительный SwiftUI: используем UIKit
UIKit остается незаменимым для обработки чувствительных к производительности сценариев, особенно при работе с большими наборами данных или сложными UI структурами.
Разработка под платформу Apple претерпела значительные изменения. Раньше мы считали, что создание ядра приложения на основе UIKit и использование SwiftUI для некоторых экранов — это хорошая идея. Сейчас мы рассмотрим разработку основной части приложения с использованием SwiftUI, а также использование UIKit в сценариях, где производительность действительно имеет значение.
Когда я говорю «основная часть приложения», я имею в виду жизненный цикл приложения и навигацию. Используя UIKit, мы можем построить навигацию, используя довольно популярный шаблон Координатор, и пушить представления SwiftUI, обернув их в UIHostingController
. Мы по-прежнему можем использовать делегат приложения для управления жизненным циклом приложения. Это отлично работает с точки зрения производительности и унаследованной кодовой базы. Но, к сожалению, у такого подхода есть свои минусы.
struct Coordinator { let navigation: UINavigationController init(navigation: UINavigationController) { self.navigation = navigation } func start() { let auth = UIHostingController(rootView: AuthView()) navigation.viewControllers = [auth] } func startMainFlow() { let main = UIHostingController(rootView: MainView()) navigation.viewControllers = [main] } } class SceneDelegate: UIResponder, UIWindowSceneDelegate { private lazy var navigation = UINavigationController() private lazy var coordinator = Coordinator(navigation: navigation) var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = navigation window?.makeKeyAndVisible() coordinator.start() } }
Каждый UIHostingController
создает свое собственное окружение SwiftUI, что означает, что вы не можете обмениваться данными через окружение. Среда в SwiftUI играет огромную роль во всем, что связано с распространением данных по иерархии представлений. SwiftUI использует окружение для многих вещей, начиная от стилизации представления и заканчивая обменом данными. Вот почему мне никогда не нравился этот подход: он не позволяет нам полностью использовать возможности SwiftUI.
Навигация в SwiftUI была очень слабой, очень трудно было построить глубокую перелинковку и модульный подход. Но с NavigationStack
, выпущенным в iOS 16, мы получили довольно новый API, основанный на данных, который позволяет нам легко создавать функциональность глубоких ссылок.
Прежде всего, я должен отметить, что создание приложения на основе UIKit по-прежнему является хорошей идеей, если вы собираетесь поддерживать версии платформы, предшествующие iOS 16. Для современных приложений, нацеленных на iOS 16 и выше, я рекомендую создавать ядро приложения с помощью SwiftUI и включать UIKit в некоторые части, где производительность SwiftUI может не соответствовать вашим ожиданиям.
@main struct ExamplesApp: App { @State private var path = NavigationPath() @State private var store = Store() var body: some Scene { WindowGroup { NavigationStack(path: $path) { HugeListView(items: store.items) .navigationDestination(for: Item.self) { item in // push item details view } .onOpenURL { url in // parse url and push next view } } } } }
Можно ожидать, что жизненный цикл приложений SwiftUI и недавно появившийся навигационный API позволят нам реализовать практически все необходимые функции: глубокие ссылки, восстановление состояния и т.д. К сожалению, в некоторых случаях производительность SwiftUI может давать сбои. Особенно если у вас есть бесконечные коллекции данных, такие как социальные ленты или макеты для календарей.
Не волнуйтесь, потому что у нас уже есть решение на этот случай под названием UIHostingConfiguration
. Это новый тип конфигурации UITableViewCell
или UICollectionViewCell
, позволяющий нам встраивать представления SwiftUI в ячейку, но при этом использовать производительные возможности UICollectionView
по работе с очередями. Этот подход отлично работает там, где производительность действительно имеет значение.
struct HugeListView: UIViewRepresentable { let items: [Item] func makeUIView(context: Context) -> UITableView { let tableVIew = UITableView() tableVIew.register(UITableViewCell.self, forCellReuseIdentifier: "cell") tableVIew.dataSource = context.coordinator return tableVIew } func updateUIView(_ uiView: UITableView, context: Context) { uiView.reloadData() } func makeCoordinator() -> Coordinator { Coordinator(items: items) } final class Coordinator: NSObject, UITableViewDataSource { let items: [Item] init(items: [Item]) { self.items = items } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let item = items[indexPath.row] let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.contentConfiguration = UIHostingConfiguration { ItemView(item: item) } return cell } } }
Помните, что UIHostingConfiguration
создается только для встраивания представлений SwiftUI в UICollectionView
или UITableView
. Не используйте NavigationLink
внутри UIHostingConfiguration
. Вместо этого используйте координатор для обработки выбора и передавайте значения в экземпляр NavigationStack
.
SwiftUI значительно развился, что делает его подходящим выбором для создания ядра современных приложений для iOS, особенно с улучшенной системой навигации в iOS 16. Однако UIKit остается незаменимым для обработки чувствительных к производительности сценариев, особенно при работе с большими наборами данных или сложными UI структурами. Надеюсь, этот пост был вам полезен.
-
Программирование3 недели назад
Конец программирования в том виде, в котором мы его знаем
-
Видео и подкасты для разработчиков6 дней назад
Как устроена мобильная архитектура. Интервью с тех. лидером юнита «Mobile Architecture» из AvitoTech
-
Магазины приложений3 недели назад
Магазин игр Aptoide запустился на iOS в Европе
-
Новости3 недели назад
Видео и подкасты о мобильной разработке 2025.8