4
votes

transmettre des données d'UIKit à SwiftUI (conteneur UIHostingController)

Comment passer des données entre UIViewController et struct ContentView ?

J'ai essayé avec ObservableObject mais je ne parviens pas à mettre à jour les données.


4 commentaires

Pourriez-vous fournir plus de détails sur ce que vous essayez de faire? Publier le code source (de ce que vous avez déjà essayé) aiderait certainement.


Avez-vous jeté un œil à updateUIViewController(_:,context:) ?


mon application (UIKit) a une vue contenant un conteneur (Swiftui) et je souhaite transmettre les données de ma vue (UIViewcontroller) à mon conteneur (UIHostingController).


Vous pouvez attacher un environmentObject à votre SwiftUI rootView. J'écrirai une réponse expliquant comment l'utiliser.


3 Réponses :


5
votes

Pour transmettre des données d'un UIViewController à un SwiftUI-Struct dans un UIHostingController vous pouvez attacher un environmentObject à SwiftUI rootView :

@EnvironmentObject var yourEnvironmentObject: TypeOfEnvironmentObject

Bien sûr, vous devrez créer un ObservableObject et l'ajouter à votre SwiftUI-Struct.

Créez l'ObservableObject:

class TypeOfEnvironmentObject: ObservableObject {
    @Published var data = "myData"
}

Ajoutez-le à votre structure:

let vc = UIHostingController(rootView: YourContentView().environmentObject(yourEnvironmentObject))


5 commentaires

Merci! Guys😃. Ouais, je l'ai déjà fait. Mais lorsque la valeur des données est mise à jour, ma structure ne prend pas les mises à jour, elle reste avec la valeur d'initialisation.


Ok, je pense que j'ai compris ce que vous essayez de faire. Si je vous ai bien compris, le Combine-Framework est ce que vous recherchez: developer.apple.com/documentation/combine/...


Avec Combine, vous pouvez connecter un éditeur dans votre UIViewController avec un abonné dans votre SwiftUI-Struct. Lorsque vos données changent, vous pouvez utiliser l'éditeur pour avertir l'abonné.


J'essaye, mais je ne comprends pas le concept. Pouvez-vous me donner un petit exemple? 😅


merci beaucoup les gars pour vos réponses. J'ai réussi avec ObservableObject et je vais essayer de détailler si cela peut aider quelqu'un d'autre.



1
votes
  1. class myclassname: ObservableObject

  2. dans la classe, créez une variable avec @Published var myvar et créez init(myvar: type) { self.myvar = myvar }

  3. dans mon UIViewController créer private var model = myclassname(myvar: XXX) et dans viewWillAppear------>let vc = myclassname(myvar: myvar) let childView = UIHostingController(rootView: ContentView(model: vc))
    1. dans ma struct ---> @ObservedObject var model: myclassname

0 commentaires

0
votes

J'ai trouvé les réponses existantes confuses / incomplètes, peut-être quelque chose a changé autour de l'inférence générique dans Swift 5.3 etc. Bien que vous puissiez ajouter un objet d'environnement à la vue de UIHostingController, cela semble entrer en conflit avec les types (c'est-à-dire que le paramètre générique de UIHostingController a besoin d'un type concret) . L'ajout d' AnyView résout ceci:

import UIKit
import SwiftUI

struct TutorialView: View {
    
    @EnvironmentObject private var integration: TutorialIntegrationService
    
    var body: some View {
        Text("Hi").navigationBarTitle("test: \(integration.id)")
    }
}

class TutorialIntegrationService: ObservableObject {
    @Published var id: Int = 0
}

class TutorialViewController: UIHostingController<AnyView> {
    
    let integration = TutorialIntegrationService()
    
    required init?(coder: NSCoder) {
        super.init(coder: coder,rootView: AnyView(TutorialView().environmentObject(integration)));
    }
}


0 commentaires