iOS 15中Form内VStack嵌套Text与DatePicker不显示问题
问题描述
- iOS 15系统中,
Form的Section内用VStack同时包含Text与.graphical样式的DatePicker时,整行内容完全不显示;替换为Image则正常,Button、Label等组件也会触发相同问题。 - iOS 16及以上版本无此异常,已在模拟器与真机验证结果一致。
原测试代码:
struct TestView: View { var body: some View { Form { Section { VStack { Text("This text prevents the row from showing up.") DatePicker("", selection: .constant(Date()), displayedComponents: .date) .datePickerStyle(.graphical) } } } } } struct TestView_Previews: PreviewProvider { static var previews: some View { TestView() } }
解决方案
这是iOS 15的Form布局bug,以下是几种可行修复方式:
方法1:给VStack添加明确高度约束
通过设置最小高度,让Form能正确计算行高:
struct TestView: View { var body: some View { Form { Section { VStack { Text("This text shows up correctly now.") DatePicker("", selection: .constant(Date()), displayedComponents: .date) .datePickerStyle(.graphical) } .frame(minHeight: 300) // 添加最小高度约束 } } } }
方法2:用UIKit容器包裹VStack
借助UIViewRepresentable封装UIKit容器,规避SwiftUI的布局问题:
struct UIViewContainer<Content: View>: UIViewRepresentable { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } func makeUIView(context: Context) -> UIView { let view = UIView() let hostingController = UIHostingController(rootView: content) hostingController.view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(hostingController.view) NSLayoutConstraint.activate([ hostingController.view.topAnchor.constraint(equalTo: view.topAnchor), hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) return view } func updateUIView(_ uiView: UIView, context: Context) {} } // 使用示例 struct TestView: View { var body: some View { Form { Section { UIViewContainer { VStack { Text("This text works properly.") DatePicker("", selection: .constant(Date()), displayedComponents: .date) .datePickerStyle(.graphical) } } } } } }
方法3:版本适配处理
针对iOS 15单独添加修复逻辑,不影响高版本:
struct TestView: View { var body: some View { Form { Section { VStack { Text("This text works across versions.") DatePicker("", selection: .constant(Date()), displayedComponents: .date) .datePickerStyle(.graphical) } .if #available(iOS 15, *) { $0.frame(minHeight: 300) } } } } } // 扩展View实现条件修饰符 extension View { @ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View { if condition { transform(self) } else { self } } }
内容的提问来源于stack exchange,提问作者programr
相关产品推荐
相关产品推荐

