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

如何获取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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 16:04:57