iOS 16下List行分隔符偏移问题求助(兼容iOS15.5+)
iOS16下List行分隔符偏移问题修复
问题场景
App最低兼容iOS15.5,升级至iOS16后,使用InsetGroupedListStyle的带分组头部List,其行分隔符出现向右偏移异常;但在iOS15.7上显示完全正常。
核心代码片段
var videoGuideRight: CGFloat { switch UIDevice.current.name { case "iPhone SE (1st generation)", "iPod touch (7th generation)": return 0.18 default: return 0.2 } } var contactRight: CGFloat { switch UIDevice.current.name { case "iPhone SE (1st generation)", "iPod touch (7th generation)": return 0.04 default: return 0.12 } } var contactLeft: CGFloat { switch UIDevice.current.name { case "iPhone SE (1st generation)", "iPod touch (7th generation)": return 0.255 default: return 0.27 } } var contactButtonWidth: CGFloat { switch UIDevice.current.name { case "iPhone SE (1st generation)", "iPod touch (7th generation)": return 1/4.25 default: return 1/5 } } var contactFrameWidth: CGFloat { switch UIDevice.current.name { case "iPhone SE (1st generation)", "iPod touch (7th generation)": return 0.175 default: return 0.15 } } var body: some View { NavigationView { VStack { List { Section(header: Text("Support")) { HStack { Image("about") Text("About") .font(.system(size: 15)) .frame(width: UIScreen.main.bounds.width * 0.65, height: 15, alignment: .center) NavigationLink(destination: AboutView()) { EmptyView() } } HStack { Image("userGuide") Text("Handbook") .font(.system(size: 15)) .frame(width: UIScreen.main.bounds.width * 0.65, height: 15, alignment: .center) NavigationLink(destination: UserGuideView()) { EmptyView() } } HStack { Image("videoGuide") Link(destination: URL(string: "https://www.tirnaelectronics.co.uk/polylingo-guide")!) { } Spacer().frame(width: UIScreen.main.bounds.width * 0.04, height: nil, alignment: .center) Text("Video Guide") .font(.system(size: 15)) .frame(width: UIScreen.main.bounds.width * 0.3, height: 15, alignment: .leading) Spacer().frame(width: UIScreen.main.bounds.width * videoGuideRight, height: nil, alignment: .center) } HStack { Image("contact") Spacer().frame(width: UIScreen.main.bounds.width * contactLeft, height: nil, alignment: .center) Text("Contact") .font(.system(size: 15)) .frame(width: UIScreen.main.bounds.width * contactFrameWidth, height: 15, alignment: .center) Spacer().frame(width: UIScreen.main.bounds.width * contactRight, height: nil, alignment: .center) Text("E-mail") .fontWeight(.bold) .frame(width: screenSize.width * contactButtonWidth, height: 20, alignment: .center) .font(.footnote) .padding(8) .background(Color.systemBlue) .cornerRadius(5) .foregroundColor(.white) .overlay( RoundedRectangle(cornerRadius: 5) .stroke(Color.systemBlue, lineWidth: 2) ) .onTapGesture{ mailto() } } } } .navigationBarTitle("More", displayMode: .inline).opacity(0.8) .listStyle(InsetGroupedListStyle()) .background(Color.init(.systemGroupedBackground)) // 弹窗代码省略... } } }
问题原因
iOS16对InsetGroupedListStyle的行分隔符布局逻辑做了调整,原代码中依赖UIScreen.main.bounds.width硬编码比例的布局方式,在新系统下会导致List无法正确识别行内容的边界,进而出现分隔符偏移。
修复方案
方案1:强制统一分隔符边距
针对iOS16及以上版本,直接设置listRowSeparatorInsets来固定分隔符的左右边距,确保和iOS15表现一致:
// 在每个HStack的末尾添加该修饰符 HStack { // 原内容 } .listRowSeparatorInsets(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0)) // 或根据系统版本适配 .listRowSeparatorInsets(if #available(iOS 16.0, *) { EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0) } else { EdgeInsets() // iOS15及之前使用默认值 })
方案2:重构布局,避免硬编码屏幕尺寸
原代码中大量使用屏幕宽度比例来控制组件尺寸,这种方式兼容性差。改用SwiftUI原生自适应布局:
// 以About行为例,重构后代码 HStack { Image("about") Text("About") .font(.system(size: 15)) Spacer() // 用Spacer替代固定宽度的frame,自动填充剩余空间 NavigationLink(destination: AboutView()) { EmptyView() } }
这种方式让布局自适应不同设备和系统版本,从根源上避免分隔符偏移问题。
方案3:统一行内容的对齐方式
给每个Section内的行添加listRowAlignment,确保内容对齐一致,帮助List正确计算分隔符位置:
Section(header: Text("Support")) { // 行内容 } .listRowAlignment(.leading)
内容的提问来源于stack exchange,提问作者Tycho Systems
相关产品推荐
相关产品推荐

