如何获取SwiftUI LiquidGlass样式TabView的宽度尺寸
如何获取SwiftUI中启用LiquidGlass样式的TabView实际宽度
iOS 18新增的LiquidGlass样式让TabView的标签栏不再占满全屏宽度,还会随页面滚动自动收缩或展开。我现在要给这个TabView适配一款2年前开发的引导组件,旧TabView样式下组件能正常对齐,但切换到LiquidGlass样式后,引导层的点击区域无法和实际标签栏匹配。
已尝试的无效方案
1. Overlay内嵌套GeometryReader
直接在TabView的overlay中嵌套GeometryReader,拿到的始终是全屏宽度,无法获取标签栏的实际可视宽度:
GeometryReader { geometry in ZStack(alignment: .bottom) { TabView { // tabitems... } .overlay(alignment: .bottom, content: { GeometryReader { geometry in HStack(spacing: 0) { Circle() .foregroundStyle(.clear) .frame(width: 45, height: 45) .showCase(order: 0, title: "Text1", cornerRadius: 30, style: .continuous, scale: 1.5) .frame(maxWidth: .infinity) Circle() .foregroundStyle(.clear) .frame(width: 45, height: 45) .showCase(order: 1, title: "Text2", cornerRadius: 30, style: .continuous, scale: 1.5) .frame(maxWidth: .infinity) Circle() .foregroundStyle(.clear) .frame(width: 45, height: 45) .showCase(order: 2, title: "Text3", cornerRadius: 30, style: .continuous, scale: 1.5) .frame(maxWidth: .infinity) } .frame(maxWidth: geometry.size.width) .allowsHitTesting(false) } }) } }
2. 使用PreferenceKey监听宽度
通过自定义PreferenceKey监听TabView背景的尺寸,结果仍只能获取到全屏宽度,无法捕获标签栏的实际宽度:
struct TabViewWidthKey: PreferenceKey { static var defaultValue: CGFloat = 0 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = nextValue() } } GeometryReader { geometry in ZStack(alignment: .bottom) { TabView { // tabitems... } .background( GeometryReader { tabGeometry in Color.clear.preference( key: TabViewWidthKey.self, value: tabGeometry.size.width ) } ) .onPreferenceChange(TabViewWidthKey.self) { width in } } }
临时可行但不通用的方案
目前只能通过硬编码屏幕宽度比例设置引导层宽度,这种方式仅适配特定设备,更换设备或屏幕尺寸后就会失效:
GeometryReader { geometry in ZStack(alignment: .bottom) { TabView { // My tabitems here } .overlay(alignment: .bottom, content: { HStack(spacing: 0) { Circle() .foregroundStyle(.clear) .frame(width: 45, height: 45) .showCase(order: 0, title: "Text1", cornerRadius: 30, style: .continuous, scale: 1.5) .frame(maxWidth: .infinity) Circle() .foregroundStyle(.clear) .frame(width: 45, height: 45) .showCase(order: 1, title: "Text2", cornerRadius: 30, style: .continuous, scale: 1.5) .frame(maxWidth: .infinity) Circle() .foregroundStyle(.clear) .frame(width: 45, height: 45) .showCase(order: 2, title: "Text3", cornerRadius: 30, style: .continuous, scale: 1.5) .frame(maxWidth: .infinity) } .frame(maxWidth: geometry.size.width * 0.72) // 仅适配特定设备 .allowsHitTesting(false) }) } }
需求
需要一种能动态获取LiquidGlass样式TabView标签栏实际宽度的方案,让引导层的点击区域能随标签栏的收缩/展开自动对齐,适配所有iOS 18+设备。
内容的提问来源于stack exchange,提问作者virtu
相关产品推荐
相关产品推荐

