SwiftUI视图嵌入UIHostingController后布局偏移问题的解决方法
问题:SwiftUI视图嵌入UIHostingController后布局挤到左上角
在基于UIKit的应用中,我开发了一个用于展示无数据状态的SwiftUI视图,通过UIHostingController嵌入展示时,视图内容被挤到屏幕左上角。该视图在纯SwiftUI项目中显示正常,但嵌入后布局异常。
SwiftUI视图代码
struct ContentView: View { var body: some View { ZStack { Color("darkerBlue") .ignoresSafeArea() VStack(spacing: 20) { Image("barbell") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 200, height: 200) // Adjust the image size Text("You don't have any lifts saved.") .font(.title) .foregroundColor(.white) .padding() Button(action: { // Handle button action }) { Text("Do it") .font(.headline) .foregroundColor(.white) .padding(EdgeInsets(top: 8, leading: 50, bottom: 8, trailing: 50)) .background(Color("lightBlue")) .cornerRadius(8) } } } } }
嵌入UIHostingController的代码
case .noLiftEvents: let emptyLogView = EmptyLogView(coordinator: self) let hostingController = UIHostingController(rootView: emptyLogView) add(hostingController) return hostingController
子控制器添加扩展方法
func add(_ child: UIViewController) { addChild(child) view.addSubview(child.view) child.didMove(toParent: self) }
问题原因
核心问题是未给UIHostingController的view添加自动布局约束。在UIKit中,添加子控制器视图时,如果不设置约束,子视图不会自动填充父容器,只会以默认的原点(0,0)和固有尺寸(intrinsicContentSize)显示,导致SwiftUI内容被压缩在左上角。
修复方法
修改add(_ child: UIViewController)扩展方法,给子视图添加约束使其完全填充父视图:
func add(_ child: UIViewController) { addChild(child) // 禁用自动转换约束,避免冲突 child.view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(child.view) // 添加四边约束,让子视图完全填充父视图 NSLayoutConstraint.activate([ child.view.topAnchor.constraint(equalTo: view.topAnchor), child.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), child.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), child.view.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) child.didMove(toParent: self) }
说明
translatesAutoresizingMaskIntoConstraints = false:必须设置,否则系统会自动生成基于frame的约束,和我们手动添加的约束产生冲突。- 四个方向的约束确保UIHostingController的view完全覆盖父视图,SwiftUI内容就能按照预期居中显示了。
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

