É a primeira vez que trabalho em um projeto que está usando SwiftUI para implementar novos fluxos, mas como os fluxos são majoritariamente UIKit, é preciso fazer uma pequena integração com na hora de exibir um fluxo em SwiftUI.
Para simular um fluxo de navegação entre telas, vamos pensar que a tela com as opções é o nosso fluxo inicial feito em UIKit (programaticamente/view code) e a tela de imóveis agendados que será exibida, é a nossa view em SwiftUI.
Para um Coordinator inicial, pensaremos em algo como
import UIKit
protocol PropertyCoordinatorProtocol: AnyObject {
func navigateToSchedule()
}
class PropertyCoordinator: PropertyCoordinatorProtocol {
private var navigationController: UINavigationController
private let viewModel: PropertyViewModel
init(navigationController: UINavigationController) {
self.navigationController = navigationController
self.viewModel = PropertyViewModel()
viewModel.coordinator = self
}
func start() {
let viewController = PropertyViewController(viewModel: viewModel)
navigationController.pushViewController(viewController, animated: false)
}
}
Para exibir a view, criaremos um método navigateToSchedule que fará a apresentação a partir da nossa Navigation Controller.
func navigateToSchedule() {
let scheduleViewController = ScheduleViewController()
navigationController.present(scheduleViewController, animated: true)
}
Ao criar ScheduleViewController, a instancia de UIHostingController é o que permite incorporar uma view SwiftUI dentro de um layout UIKit.
private lazy var mainView: UIView = {
let view = ScheduleView()
let controller = UIHostingController(rootView: view)
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
return controller.view
}()
O addChild(controller)
adiciona o UIHostingController como filho do controlador atual, o que é necessário para gerenciar corretamente os ciclos de vida das views dentro de um view controller pai.
A view controller exibida será assim
import UIKit
import SwiftUI
final public class ScheduleViewController: UIViewController {
private lazy var mainView: UIView = {
let view = ScheduleView()
let controller = UIHostingController(rootView: view)
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
return controller.view
}()
public override func loadView() {
self.view = UIView()
view.backgroundColor = .clear
setupHierarchy()
setupConstraints()
}
func setupHierarchy() {
view.addSubview(mainView)
}
func setupConstraints() {
guard let superview = self.mainView.superview else { return }
NSLayoutConstraint.activate([
mainView.topAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.topAnchor),
mainView.bottomAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.bottomAnchor),
mainView.trailingAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.trailingAnchor),
mainView.leadingAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.leadingAnchor)
])
}
public override func viewDidLoad() {
super.viewDidLoad()
}
public override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
mainView.frame = view.bounds
}
}
E na View Controller principal, teremos um método que será chamado quando o botão for clicado
@objc func goToScheduleView() {
viewModel.showScheduleView()
}
E a view model terá um método que chamará o Coordinator
func showScheduleView() {
coordinator?.navigateToSchedule()
}
Top comments (0)