You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UIHostingController嵌入UIScrollView后高度异常问题求助

UIHostingController嵌入UIScrollView无高度问题的解决方案

问题描述

将UIHostingController放置在UIScrollView中,呈现SummaryViewController时视图出现无高度的异常(如图所示)。手动给SwiftUI视图设置高度可正常显示,但希望避免硬编码高度值。

视图无高度的异常显示

原代码问题分析

原代码存在几个关键问题:

  1. 未将UIHostingController添加为当前控制器的子控制器,导致其内部SwiftUI视图无法正确触发布局计算。
  2. 手动设置了hosting.view的固定高度,违背了自动布局的初衷。
  3. UIStackView使用equalSpacing分布,在只有单个子视图时无法正确传递尺寸约束。

修复后的代码

class SummaryViewController: UIViewController {
    
    var id: String = ""
    var sport: String = ""

    lazy var scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()
    
    lazy var stackView: UIStackView = {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.distribution = .fill // 单个子视图时使用fill分布更合理
        stackView.spacing = 30
        stackView.translatesAutoresizingMaskIntoConstraints = false
        
        return stackView
    }()
    lazy var contentView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .systemGroupedBackground
        let hosting = UIHostingController(rootView: SummaryView(id: id, sport: sport))
        
        // 关键步骤:将UIHostingController添加为子控制器,确保视图生命周期正常
        addChild(hosting)
        hosting.didMove(toParent: self)
        
        view.addSubview(scrollView)
        scrollView.addSubview(contentView)
        contentView.addSubview(stackView)

        stackView.addArrangedSubview(hosting.view)
        
        scrollView.insetsLayoutMarginsFromSafeArea = false
        NSLayoutConstraint.activate([
            // ScrollView约束
            scrollView.topAnchor.constraint(equalTo: view.topAnchor),
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            
            // ContentView约束,固定宽度确保ScrollView正确滚动
            contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
            contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
            contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
            
            // StackView约束
            stackView.topAnchor.constraint(equalTo: contentView.topAnchor),
            stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            
            // 约束HostingView的宽度,让SwiftUI视图能自动计算高度
            hosting.view.leadingAnchor.constraint(equalTo: stackView.leadingAnchor),
            hosting.view.trailingAnchor.constraint(equalTo: stackView.trailingAnchor)
        ])
    }
}

核心修复点

  • 添加子控制器:必须通过addChild和didMove(toParent:)将UIHostingController关联到当前控制器,否则SwiftUI视图无法正确计算自身尺寸。
  • 移除固定高度约束:让SwiftUI视图根据内容自动计算高度,无需硬编码。
  • 约束HostingView宽度:明确的宽度约束是SwiftUI视图计算高度的前提,确保其能基于父容器宽度自适应内容高度。
  • 调整StackView分布:单个子视图场景下,fill分布能正确传递子视图的尺寸约束给上层布局。

内容的提问来源于stack exchange,提问作者GILL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 02:50:42