Te damos la respuesta a este inconveniente, al menos eso creemos. Si tienes inquietudes dínoslo, que con placer te ayudaremos
Solución:
Los controladores de vista no son solo para la escena de nivel superior. A menudo colocamos controladores de vista dentro de controladores de vista. Se llama “contención del controlador de vista” y/o “controladores de vista secundarios”. (Por cierto, los contenedores de controladores de vista son, en general, una excelente manera de combatir la sobrecarga de controladores de vista en las aplicaciones UIKit tradicionales, dividiendo escenas complicadas en múltiples controladores de vista).
Asi que,
-
Adelante, usa
UIHostingController
:let controller = UIHostingController(rootView: ...)
y;
-
Agregue el controlador de vista y luego puede agregar el controlador de alojamiento como un controlador de vista secundario:
addChild(controller) view.addSubview(controller.view) controller.didMove(toParent: self)
Obviamente, también establecería el
frame
o las restricciones de diseño para el controlador de alojamientoview
.Ver el Implementación de un controlador de vista de contenedor sección de la
UIViewController
documentación para obtener información general sobre cómo incrustar un controlador de vista dentro de otro.
Por ejemplo, imaginemos que tuviéramos una vista de SwiftUI para representar un círculo con texto:
struct CircleView : View
@ObservedObject var model: CircleModel
var body: some View
ZStack
Circle()
.fill(Color.blue)
Text(model.text)
.foregroundColor(Color.white)
Y digamos que este era el modelo de nuestra vista:
import Combine
class CircleModel: ObservableObject
@Published var text: String
init(text: String)
self.text = text
Luego, nuestro controlador de vista UIKit podría agregar la vista SwiftUI, establecer su marco/restricciones dentro del UIView
y actualice su modelo como mejor le parezca:
import UIKit
import SwiftUI
class ViewController: UIViewController
private weak var timer: Timer?
private var model = CircleModel(text: "")
override func viewDidLoad()
super.viewDidLoad()
addCircleView()
startTimer()
deinit
timer?.invalidate()
private extension ViewController
func addCircleView()
let circleView = CircleView(model: model)
let controller = UIHostingController(rootView: circleView)
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controller.view)
controller.didMove(toParent: self)
NSLayoutConstraint.activate([
controller.view.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5),
controller.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5),
controller.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
controller.view.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
func startTimer()
var index = 0
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) [weak self] _ in
index += 1
self?.model.text = "Tick (index)"
Tengo una idea en mente.
- Envuelva SwiftUI con un
UIHostingController
- Inicializar el controlador
- Agregue el nuevo controlador como un controlador de vista secundario
- Agregue la vista del controlador como una subvista a donde debería ir
Por lo tanto:
addChild(hostingViewController)
hostingViewController.view.frame = ...
view.addSubview(hostingViewController.view)
hostingViewController.didMove(toParent: self)
Un controlador de vista siempre usa otros controladores de vista como vistas.
Stanford CS193P, https://youtu.be/w7a79cx3UaY?t=679
Referencia
- Cómo agregar la vista de un UIViewController como subvista
- Coloque UIViewController dentro de UIView
- Usar UIViewController como celda de TableView
Valoraciones y reseñas
Si haces scroll puedes encontrar las reseñas de otros programadores, tú asimismo tienes la libertad de mostrar el tuyo si te gusta.