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

如何让List内容穿透带材质背景的底部栏实现模糊效果 无需知晓底部栏高度

实现方案

优先推荐iOS 15+的原生最优解,使用safeAreaInset修饰符即可完全规避手动计算底部栏高度的问题,效果和系统导航栏的穿透模糊完全一致:

struct ContentView: View {
    var body: some View {
        NavigationView {
            List(1...30, id:\.self) { i in
                Rectangle()
                    .foregroundColor(Color.random)
                    .frame(height: 36)
            }
            .listStyle(PlainListStyle())
            // 关键:将底部栏作为底部安全区内嵌视图添加
            .safeAreaInset(edge: .bottom) {
                Text("Bottom bar")
                    .font(.title)
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(.bar) // 自带毛玻璃模糊效果
            }
            .navigationTitle("Some Nav Title")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

extension Color {
    static var random: Color {
        return Color(
            red: .random(in: 0...1),
            green: .random(in: 0...1),
            blue: .random(in: 0...1)
        )
    }
}

方案原理

  • safeAreaInset会自动计算传入的底部视图高度,给List底部添加对应大小的原生内边距,滚动到底部时最后一个列表项刚好完整显示在底部栏上方,无需手动写死高度
  • List默认撑满全屏,底部栏叠加在List底部区域之上,.bar材质自带毛玻璃效果,滚动的列表内容会自然穿透底部栏呈现模糊效果,和顶部导航栏表现完全一致
  • 无需额外嵌套ZStack,横竖屏切换、动态修改底部栏内容时都能自动适配,不需要额外处理。

如果需要兼容iOS 15以下版本,可以使用GeometryReader动态读取底部栏高度的方案:

struct ContentView: View {
    @State private var bottomBarHeight: CGFloat = 0
    
    var body: some View {
        NavigationView {
            ZStack(alignment: .bottom) {
                List(1...30, id:\.self) { i in
                    Rectangle()
                        .foregroundColor(Color.random)
                        .frame(height: 36)
                }
                .listStyle(PlainListStyle())
                .padding(.bottom, bottomBarHeight) // 动态设置底部内边距
                
                Text("Bottom bar")
                    .font(.title)
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(.bar)
                    // 动态读取自身渲染高度
                    .background(GeometryReader { proxy in
                        Color.clear.onAppear {
                            bottomBarHeight = proxy.size.height
                        }
                    })
            }
            .navigationTitle("Some Nav Title")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

extension Color {
    static var random: Color {
        return Color(
            red: .random(in: 0...1),
            green: .random(in: 0...1),
            blue: .random(in: 0...1)
        )
    }
}

该方案同样不需要提前知晓底部栏高度,通过GeometryReader动态获取实际渲染高度赋值给内边距即可适配所有场景。


效果示例:
底部栏需要实现模糊效果

内容的提问来源于stack exchange,提问作者Steve M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 02:45:03