---
title: "SwiftUI dentro UIKit: collegare due mondi"
url: https://www.sofapps.it/it/blog/swiftui-within-uikit/
date: 2021-03-24
author: Costantino Pistagna
language: it
translated_from: en
tags: [SwiftUI, Swift, Tutorial]
---

# SwiftUI dentro UIKit: collegare due mondi

> Un proof of concept nato da una chiacchierata su Clubhouse: invece di migrare un intero progetto, si riscrive in SwiftUI solo il contenuto di una UITableViewCell, ospitato in un UIHostingController. UIKit comunica con la view SwiftUI tramite NotificationCenter e Combine, e lo scrolling resta fluido. L'approccio è decisamente poco elegante, e il codice completo è su GitHub.

Ieri sera ho partecipato a una room su Clubhouse molto interessante, in cui si parlava di SwiftUI e di interoperabilità con Swift. Il resto dell'articolo è un proof-of-concept che esplora alcune idee emerse durante la chat con
Dimitri Giani, Stefano Mondino e Andrea Mengoli.

SwiftUI offre ottime prestazioni e rende semplice costruire anche layout complessi, ma spostare un intero progetto da UIKit a SwiftUI non è sempre fattibile, per molte ragioni (maturità del framework, tempi di consegna, e così via). Allora perché non prendere il meglio dei due mondi?

Esistono decine di <a href="https://www.swiftbysundell.com/articles/swiftui-and-uikit-interoperability-part-2/">tutorial</a> e <a href="https://www.avanderlee.com/swiftui/integrating-swiftui-with-uikit/">articoli</a> sull'uso di **UIHostingController** che, ad oggi, sembra l'unica strada percorribile per realizzare quanto detto sopra. Ieri sera però ci siamo concentrati su un punto di vista un po' diverso:

>Spostare in SwiftUI solo porzioni di codice molto piccole.

Per esempio, una delle cose più odiate da ogni sviluppatore iOS è dover usare lo Storyboard per disegnare le celle di una **UITableView/UICollectionView**.

Non sarebbe bello migrare in SwiftUI solo il contenuto di una UITableViewCell, per migliorare prestazioni, manutenibilità e semplicità, rendendo così a prova di futuro almeno una parte del nostro codice? Era la proposta di
Dimitri Giani.

Tutti, io compreso, eravamo scettici: UIHostingController sembrava un approccio molto complicato e sovradimensionato per un compito così critico dal punto di vista delle prestazioni (parliamo dei componenti riutilizzabili di una UIScrollView).

>Inutile dire che mi sbagliavo. Almeno in un primissimo test, descritto nel resto di questo articolo, l'approccio funziona benissimo, con qualche accorgimento, e senza alcun problema di prestazioni.

![Schizzo di uno Storyboard: una table view con una cella prototipo vuota e una view SwiftUI disegnata a mano, indicata come rootView di un UIHostingController](https://www.sofapps.it/blog/swiftui-within-uikit/swiftui-with-uikit-shot1.jpg)

Sopra c'è una bozza di ciò che vogliamo ottenere. Come si vede, la UITableViewCell deve conoscere la proprietà **rootView** del corrispondente UIHostingController e, poiché ogni istanza di UITableViewCell deve essere riutilizzabile, dobbiamo mantenere questa proprietà unica.

![Codice di CustomTableViewCell: crea un UIHostingController, ne vincola la view alla contentView in awakeFromNib e invia una notifica in configure](https://www.sofapps.it/blog/swiftui-within-uikit/swiftui-with-uikit-shot2.png)

Rendiamo la nostra CustomTableViewCell consapevole di questo creando una costante private che istanzia un **UIHostingController** e configurando l'oggetto nella primissima fase di **awakeFromNib**.

Il metodo *configure(title:sfIcon:)* è solo un segnaposto che sfrutta l'approccio **Combine** / **publisher** per comunicare con la corrispondente view **SwiftUI**. Qui inviamo una semplice Notification quando dobbiamo configurare la SwiftUIView.

Da notare che dobbiamo specificare la proprietà **object**, perché vogliamo gestire *solo* una specifica istanza dell'oggetto.

>Sì, lo ammetto, sembra davvero un hack...

![Codice di GuestView, una HStack SwiftUI con un'immagine e un titolo che si aggiorna con un publisher di NotificationCenter e adotta Equatable](https://www.sofapps.it/blog/swiftui-within-uikit/swiftui-with-uikit-shot3.png)

La controparte SwiftUI è molto semplice. Creiamo solo un contenitore HStack che ospita sia l'immagine di anteprima sia il titolo. Regoliamo anche il frame in modo da occupare tutto lo spazio disponibile senza ulteriori vincoli (la UIView che ci contiene sarà responsabile delle dimensioni del contenitore, N.d.R.). **onReceive** aggiorneremo i relativi stati, facendo in modo che la view si aggiorni da sola dove serve.

Noterete che ho fatto adottare Equatable alla struct stessa, aggiungendo sia un *id* sia il relativo metodo in override. Serve per distinguere se dobbiamo scartare o prendere in considerazione la notifica pubblicata ricevuta da **NotificationCenter**.

Ed è tutto. Anche se questa soluzione è un'architettura di cella molto hackish e sovradimensionata, sono davvero colpito dai risultati: lo scrolling è fluido e senza il minimo glitch.

Sono abbastanza sicuro che esistano altri modi per ottenere lo stesso risultato con meno boilerplate e/o in modo molto più elegante (soprattutto per la comunicazione da UIKit a SwiftUI).

Non vedo l'ora di leggere i vostri commenti e di vedere i vostri commit. Il codice completo è <a href="https://github.com/valvoline/UIHostingTableViewTest">disponibile qui</a> su GITHUB.
