You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何在iOS 26应用中实现类似Apple Music的Liquid Glass栏效果?

如何在iOS 26应用中实现类似Apple Music的Liquid Glass栏效果?

嘿,我刚好研究过iOS 26这套Liquid Glass设计的实现思路,给你整理几个关键步骤,亲测可行:

  • 先搭好基础布局结构
    你需要两个核心视图:一个自定义的悬浮栏(比如命名为LiquidGlassBar)和底部的Tab Bar。用Auto Layout把悬浮栏固定在初始的悬浮位置(比如距离顶部100pt),Tab Bar可以用系统的UITabBar或者自定义实现,初始状态正常显示所有按钮。记得给悬浮栏加上UIBlurEffect(用.systemUltraThinMaterial样式最接近iOS 26的Liquid Glass质感),套在UIVisualEffectView里,先把通透感做出来。

  • 监听滚动触发动画
    给页面的滚动视图(UIScrollViewUICollectionView)添加滚动监听,通过contentOffset.y判断滚动方向和偏移量。设定一个阈值(比如向下滚动超过100pt),当达到这个阈值时触发收缩动画,向上滚动回到阈值内时触发展开动画。这里要加个状态标记(比如isAnimating),避免动画反复触发。

  • 实现Liquid Glass的平滑动画
    UIViewPropertyAnimator来做弹性动画(dampingRatio设为0.8左右,接近Apple的流畅感),核心动画分两部分:

    1. 悬浮栏的流动:修改它的顶部约束,让它平滑移动到Tab Bar的位置,同时可以微调模糊程度或者透明度,增强融合感。
    2. Tab Bar的收缩:隐藏除核心按钮外的其他Tab项(清空图标、标题并禁用),同时收缩Tab Bar的宽度(如果是自定义Tab Bar),让它变成单个圆形按钮。
  • 代码示例片段
    这里给你一段简化的实现代码,你可以根据自己的需求调整:

    // 定义状态标记和约束引用
    private var isAnimating = false
    @IBOutlet weak var liquidBarTopConstraint: NSLayoutConstraint!
    @IBOutlet weak var tabBarWidthConstraint: NSLayoutConstraint!
    @IBOutlet weak var tabBar: UITabBar!
    
    // 监听滚动事件
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let scrollOffset = scrollView.contentOffset.y
        let collapseThreshold: CGFloat = 100
        let expandThreshold: CGFloat = 50
    
        if scrollOffset > collapseThreshold && !isAnimating {
            isAnimating = true
            animateCollapse()
        } else if scrollOffset < expandThreshold && isAnimating {
            isAnimating = false
            animateExpand()
        }
    }
    
    // 收缩动画:悬浮栏下落 + Tab Bar收缩
    private func animateCollapse() {
        UIViewPropertyAnimator(duration: 0.4, dampingRatio: 0.8) {
            self.liquidBarTopConstraint.constant = self.view.frame.height - 80
            // 隐藏非核心Tab项
            self.tabBar.items?.enumerated().forEach { index, item in
                if index != 2 { // 假设第3个是核心按钮
                    item.isEnabled = false
                    item.title = ""
                    item.image = nil
                }
            }
            self.tabBarWidthConstraint.constant = 60
            self.view.layoutIfNeeded()
        }.startAnimation()
    }
    
    // 展开动画:恢复悬浮栏和Tab Bar
    private func animateExpand() {
        UIViewPropertyAnimator(duration: 0.4, dampingRatio: 0.8) {
            self.liquidBarTopConstraint.constant = 100
            // 恢复所有Tab项的图标和标题,这里替换成你自己的资源
            self.tabBar.items?.forEach { item in
                item.isEnabled = true
                // 示例:恢复图标和标题
                item.image = UIImage(systemName: "house")
                item.title = "首页"
            }
            self.tabBarWidthConstraint.constant = self.view.frame.width
            self.view.layoutIfNeeded()
        }.startAnimation()
    }
    
  • 额外细节优化

    • 动画期间可以暂时禁用悬浮栏和Tab Bar的交互,避免误操作;
    • 适配不同屏幕尺寸时,所有布局都用Auto Layout约束,不要用固定frame;
    • 如果需要更逼真的“液体流动”形变,可以结合Core Animation的CAShapeLayer,给悬浮栏做路径动画,让边缘更圆润地过渡到Tab Bar。

内容来源于stack exchange

火山引擎 最新活动