首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI -如何从SwiftUI访问UIHostingController

SwiftUI -如何从SwiftUI访问UIHostingController
EN

Stack Overflow用户
提问于 2021-04-30 11:54:01
回答 2查看 429关注 0票数 3

我有SwiftUI页面,它是从UIKit视图中导航的。我想给这个页面设置一个标题,我要做的是

代码语言:javascript
复制
// code of UIKit view
let controller = UIHostingController(rootView: SwiftUIView())
controller.title = "title"
MyNavigationManager.present(controller)

有没有办法在SwiftUI中访问托管控制器?

然后我可以编写像self.hostingController?.title = "title"这样的代码

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-30 21:34:42

这是一个可能方法的演示-使用外部配置包装器类来保持到控制器的弱链接,并将其注入到SwiftUI视图中(作为替代,也可以使其ObservableObject以与其他全局属性和逻辑相结合)。

使用Xcode12.5/ iOS 14.5进行测试

代码语言:javascript
复制
class Configuration {
    weak var hostingController: UIViewController?    // << wraps reference
}

struct SwiftUIView: View {
    let config: Configuration   // << reference here

    var body: some View {
        Button("Demo") {
            self.config.hostingController?.title = "New Title"
        }
    }
}

let configuration = ExtConfiguration()
let controller = UIHostingController(rootView: SwiftUIView(config: configuration))

// injects here, because `configuration` is a reference !!
configuration.hostingController = controller

controller.title = "title"
MyNavigationManager.present(controller)
票数 3
EN

Stack Overflow用户

发布于 2021-08-17 13:45:04

我选择了一个不同的选项-子类NSHostingController,这样它就可以将自己作为一个环境变量来提供。

代码语言:javascript
复制
struct SwiftUIView: View {
    @EnvironmentObject var host:HSHostWrapper

    var body: some View {
        Button("Dismiss") {
            host.controller?.dismiss(self)
        }
    }
}

let controller = HSHostingController(rootView: SwiftUIView())

这是通过以下HSHostingController (在HSSwiftUI package中提供)实现的

代码语言:javascript
复制
import Foundation
import SwiftUI


#if os(iOS) || os(tvOS)
    import UIKit
    public typealias ViewController = UIViewController
    public typealias HostingController = UIHostingController
#elseif os(OSX)
    import AppKit
    public typealias ViewController = NSViewController
    public typealias HostingController = NSHostingController
#endif

public class HSHostWrapper:ObservableObject {
    public weak var controller:ViewController?
}


/// allows root view (and children) to access the hosting controller by adding
/// @EnvironmentObject var host:HSHostWrapper
/// then e.g. host.controller?.dismiss()
public class HSHostingController<Content>:HostingController<ModifiedContent<Content,SwiftUI._EnvironmentKeyWritingModifier<HSHostWrapper?>>> where Content : View {
    
    public init(rootView:Content) {
        let container = HSHostWrapper()
        let modified = rootView.environmentObject(container) as! ModifiedContent<Content, _EnvironmentKeyWritingModifier<HSHostWrapper?>>
        super.init(rootView: modified)
        container.controller = self
    }
  
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67327974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档