标签: uihostingcontroller

UIHostingController 应该扩展以适应内容

我有一个自定义UIViewControllerRepresentable(与布局相关的代码如下所示)。这试图复制本机 SwiftUI ScrollView,除了它从底部滚动,除了顶部。

查看层次结构

view: UIView
|
\- scrollView: UIScrollView
   |
   \- innerView: UIView
      |
      \- hostingController.view: SwiftUI hosting view
Run Code Online (Sandbox Code Playgroud)

当视图初始化时,这一切都按预期工作。托管视图填充了其内容,并且约束确保滚动视图的contentSize设置正确。

但是,当宿主视图的内容更改时,hostingController.view不会调整大小以适合其内容。

从 Xcode 中的应用程序捕获 UI 的屏幕截图。 显示宿主控制器的内容扩展到宿主视图本身的边界之后,没有正确调整大小。

绿色:正如预期的那样,滚动视图与托管视图控制器的大小相匹配。

蓝色:托管视图本身。它保持第一次加载时的大小,并且不会像它应该的那样消耗。

红色:托管视图中的堆栈视图。在此屏幕截图中,内容已添加到堆栈中,导致其展开。结果,您可以看到大小的差异。

UIHostingController(蓝色)应该展开以适应其内容(红色)。

滚动视图的内容大小没有明确设置,因为这是由自动布局处理的。

如果有帮助,约束代码如下所示。

class UIBottomScrollViewController<Content: View>: UIViewController, UIScrollViewDelegate {
    var hostingController: UIHostingController<Content>! = nil

    init(rootView: Content) {
        self.hostingController = UIHostingController<Content>(rootView: rootView)
        super.init(nibName: nil, bundle: nil)
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    var scrollView: UIScrollView = UIScrollView()
    var innerView = UIView()

    override …
Run Code Online (Sandbox Code Playgroud)

ios swift ios-autolayout swiftui uihostingcontroller

21
推荐指数
5
解决办法
3429
查看次数

在 iOS 15 上,UIHostingController 向其托管 SwiftUI 视图 (_UIHostingView) 添加了一些奇怪的额外填充

更新:2022-09-26

\n

此问题已在 iOS 16 上修复。尽管即使使用 iOS 16 SDK 编译项目,该问题在 iOS 15 上仍然存在。

\n

原问题:

\n

在 iOS 15 上,正在UIHostingController向其托管 SwiftUI 视图添加一些奇怪的额外填充 ( _UIHostingView)。

\n

请参见下面的屏幕截图(蓝色=额外空间,红色=实际视图\xe2\x80\x99s):

\n

在此输入图像描述

\n

有谁知道为什么会发生这种情况?

\n

我已经报告了这个错误,Apple 人员:FB9641883

\n

PD:我有一个工作项目重现了我附加到反馈助手问题的问题。如果有人想要的话我也可以上传。

\n

swiftui uihostingcontroller ios15

19
推荐指数
1
解决办法
6662
查看次数

为什么 SwiftUI UIHostingController 有额外的间距?

我正在尝试使用 UIHostingController 将 SwiftUI 视图添加到 UIKit 视图,并且它显示额外的间距(此示例是为了模拟生产应用程序上的问题而制作的)。这是屏幕截图。

在此输入图像描述

布局概览:

View
  UIStackView
    UIImageView
    UIView(red)
    UIHostingController
    UIView(blue)
Run Code Online (Sandbox Code Playgroud)

问题: 快速 UI 视图 (UIHostingController) 显示在红色和蓝色视图之间,它在分隔线之后显示额外的间距。间距根据 SwiftUI 视图的大小而变化。

如果我减少行数(Hello World 文本)或减少间距,它似乎工作正常。

这是完整的源代码(https://www.sendspace.com/file/ux0xt7):

ViewController.swift(主视图)

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var mainStackView: UIStackView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        addView()
    }


    private func addView() {
        mainStackView.spacing = 0
        mainStackView.alignment = .fill
        
        let imageView = UIImageView()
        imageView.image = UIImage(named: "mountain")
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true …
Run Code Online (Sandbox Code Playgroud)

autolayout swift swiftui uihostingcontroller ios15

19
推荐指数
3
解决办法
6566
查看次数

嵌入 UIHostingController 时无法将 SwiftUI 视图放置在 SafeArea 之外

我有一个简单的 SwiftUI 视图,其中包含 3 个文本元素:

\n
struct ImageDescriptionView: View {\n    var title: String?\n    var imageDescription: String?\n    var copyright: String?\n\n    var body: some View {\n        VStack(alignment: .leading) {\n        \n            if let title = title {\n                Text(title)\n                    .fontWeight(.bold)\n                    .foregroundColor(.white)\n                    .frame(maxWidth: .infinity, alignment: .leading)\n            }\n        \n            if let imageDescription = imageDescription {\n                Text(imageDescription)\n                    .foregroundColor(.white)\n                    .fontWeight(.medium)\n                    .frame(maxWidth: .infinity, alignment: .leading)\n            }\n        \n            if let copyright = copyright {\n                Text(copyright)\n                    .font(.body)\n                    .foregroundColor(.white)\n                    .frame(maxWidth: .infinity, alignment: .leading)\n            }\n        \n        }\n        .background(\n            Color.blue\n        )\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

SwiftUI …

uikit safearealayoutguide swiftui uihostingcontroller

15
推荐指数
3
解决办法
5204
查看次数

SwiftUI - 如何从 SwiftUI 访问 UIHostingController

我有 SwiftUI 页面,它是从 UIKit 视图导航的。我想为此页面设置标题,我正在做的是

// code of UIKit view
let controller = UIHostingController(rootView: SwiftUIView())
controller.title = "title"
MyNavigationManager.present(controller)

Run Code Online (Sandbox Code Playgroud)

有没有办法可以访问 SwiftUI 中的托管控制器?

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

swiftui uihostingcontroller

11
推荐指数
2
解决办法
9736
查看次数

如何检查视图控制器是否属于 UIHostingController 类型

我有一个 UIHostingController,它托管一个名为 CatalogView 的 SwiftUI 视图。显示它时,会附加一个环境对象,因此基本上从 UIKit 来看,它显示如下:

let rootCatalogView = CatalogView()

let appState = AppState.get()
let catalogView = UIHostingController(rootView: rootCatalogView.environmentObject(appState))

navigationController.pushViewController(catalogView, animated: true)
Run Code Online (Sandbox Code Playgroud)

现在稍后我需要检查这个 UIHostingController 是否在 navigationController.viewControllers 列表中

type(of:) 显示以下内容,这是有意义的:

UIHostingController<ModifiedContent<CatalogView, _EnvironmentKeyWritingModifier<Optional<AppState>>>>
Run Code Online (Sandbox Code Playgroud)

诸如 vc.self is UIHostingController.Type 或 vc.self is UIHostingController< CatalogView >.Type 之类的东西都返回 false (vc 是 navigationController.viewControllers 的元素

以下显然有效,它返回 true,但是 UIHostingController 初始化中的任何更改都会更改其类型

vc.isKind(of: UIHostingController<ModifiedContent<CatalogView, _EnvironmentKeyWritingModifier<Optional<StoreManager>>>>.self)
Run Code Online (Sandbox Code Playgroud)

我如何检查视图控制器是否属于 UIHostingController 类型?或者至少我如何将控制器投射到 UIHostingController 以便我可以检查其根视图?

generics ios swift swiftui uihostingcontroller

10
推荐指数
2
解决办法
4768
查看次数

将 SwiftUI 视图添加到 UITableViewCell contentView

我目前正在尝试在 UIViewControllerRepresentable 中实现 UITableViewController,其中单元格的内容再次是 SwiftUI 视图。我不能使用 SwiftUI 列表,因为我想稍后添加一个 UISearchController。
因为我希望能够将自定义 SwiftUI 视图作为每个单元格的内容,所以我不可能在单元格内没有 SwiftUI 视图的情况下做到这一点。
我当前不起作用的代码如下所示:

class SearchableListCell: UITableViewCell {
    let contentController: UIViewController

    init(withContent content: UIViewController, reuseIdentifier: String) {
        self.contentController = content

        super.init(style: .default, reuseIdentifier: reuseIdentifier)

        self.addSubview(self.contentController.view)
        // Tried also
        // self.contentView.addSubview(self.contentController.view)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

struct SearchableList: UIViewControllerRepresentable {
    let data: [String]

    var viewBuilder: (String) -> ContentView

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> UITableViewController {
        return context.coordinator.tableViewController …
Run Code Online (Sandbox Code Playgroud)

uitableview swift swiftui uihostingcontroller

7
推荐指数
1
解决办法
4312
查看次数

当根控制器是 UIHostingController 时隐藏 UINavigationController 的 navigationBar

我正在努力隐藏navigationBar,如果根控制器不是 SwiftUI,它将正确隐藏UIHostingController

我尝试了以下方法:

  • navigationController.isNavigationBarHidden = true创建后设置,在viewDidLoadviewWillAppear

  • 为's添加.navigationBarHidden(true)和。.navigationBarBackButtonHidden(true)UIHostingControllerrootView

这可能是苹果的一个错误吗?我使用的是 Xcode 11.6。

我所有的尝试在一起:

class LoginController: UINavigationController, ObservableObject
{
    static var newAccount: LoginController
    {
        let controller = LoginController()
        let view = LoginViewStep1()
            .navigationBarHidden(true)
            .navigationBarBackButtonHidden(true)
        controller.viewControllers = [UIHostingController(rootView: view)]
        controller.isNavigationBarHidden = true
        return controller
    }
    
    override func viewWillAppear(_ animated: Bool)
    {
        super.viewWillAppear(animated)
        
        self.isNavigationBarHidden = true
    }

    override func viewDidLoad()
    {
        super.viewDidLoad()

        self.isNavigationBarHidden = true
    }
}

struct LoginViewStep1: View
{ …
Run Code Online (Sandbox Code Playgroud)

uinavigationbar uinavigationcontroller ios swiftui uihostingcontroller

7
推荐指数
1
解决办法
2953
查看次数

SwiftUI UIHostingController 导航标题动画损坏

当我使用 UIHostingController 将新的 SwiftUI.View 推送到现有 UIKit UIViewController 的导航堆栈时,导航栏中标题的动画被破坏。我在 Xcode 12.0 中在一个全新的项目上进行了测试。

仔细观察标题“UIHostingController”。您可以看到该动画与普通的推送动画有何不同,它只是凭空“出现”,看起来很破碎。第二个动画已经从 SwiftUI.NavigationLink 中发生,看起来不错。

如果您想尝试一下,这里是示例项目的链接: https://www.dropbox.com/s/mjkuzhpsb6yvlir/HostingControllerTest.zip ?dl=0

请参阅此 GIF 图像:(如果您看不到 GIF 动画,请在另一个浏览器选项卡中打开)

这是背后的代码:

class ViewController: UIViewController {
    private let button = UIButton(frame: .zero)

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "UIHostingController Title Test"
        self.view.backgroundColor = UIColor.white
        
        self.view.addSubview(self.button)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitle("Push UIHostingController", for: .normal)
        button.addTarget(self, action: #selector(Self.pushVC), for: .touchUpInside)
        button.setTitleColor(.blue, for: .normal)
        
        NSLayoutConstraint.activate([
            button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
            button.widthAnchor.constraint(equalTo: self.view.widthAnchor),
            button.heightAnchor.constraint(equalToConstant: 50)
        ])
    }
    
    @objc private func pushVC() {
        let vc …
Run Code Online (Sandbox Code Playgroud)

xcode ios swift swiftui uihostingcontroller

7
推荐指数
1
解决办法
2452
查看次数

当 superview 在 vi​​ewDidAppear 之前翻译时,UIHostingController 视图的转换不同步

给定: UIHostingController 托管在 UIKit 超级视图中。

时间: Superview 变换在 viewDidAppear 之前修改。在此示例中,向下移动了 200 点。

然后:对超级视图变换的后续更改将不同步。在此示例中,我将其移回原来的位置。尽管 SwiftUI 内容似乎位于正确的位置,但点击注册仍位于原始位置,因此为了点击,我需要点击正在显示的区域下方。(见截图

Xcode 12.3 - iPhone 8 Sim (iOS 14)

struct ContentView: View {
    var body: some View {
        Button(action: { print("Testing 123") }, label: {
            Text("Button")
        })
        .padding()
        .background(Color.gray)
    }
}

class RootVC: UIViewController {
    let hostingVC = UIHostingController(rootView: ContentView())
    
    override func viewDidLoad() {
        super.viewDidLoad()
        hostingVC.view.translatesAutoresizingMaskIntoConstraints = false
        view.translatesAutoresizingMaskIntoConstraints = false
        
        addChild(hostingVC)
        view.addSubview(hostingVC.view)
        hostingVC.didMove(toParent: self)
        
        hostingVC.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        hostingVC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true …
Run Code Online (Sandbox Code Playgroud)

uikit ios swiftui uihostingcontroller

6
推荐指数
1
解决办法
781
查看次数