DEV Community

Cover image for Integrando SwiftUI em UIKit e implementando View com Coordinator
Lys
Lys

Posted on

3 1 1 1 1

Integrando SwiftUI em UIKit e implementando View com Coordinator

É 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.

Gif de gravação de tela mostrando ação do botão

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)
    }
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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
}()
Enter fullscreen mode Exit fullscreen mode

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 
    }
}
Enter fullscreen mode Exit fullscreen mode

E na View Controller principal, teremos um método que será chamado quando o botão for clicado

@objc func goToScheduleView() {
    viewModel.showScheduleView()
}
Enter fullscreen mode Exit fullscreen mode

E a view model terá um método que chamará o Coordinator

func showScheduleView() {
    coordinator?.navigateToSchedule()
}
Enter fullscreen mode Exit fullscreen mode

Código no github

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay