如何在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里,先把通透感做出来。监听滚动触发动画
给页面的滚动视图(UIScrollView或UICollectionView)添加滚动监听,通过contentOffset.y判断滚动方向和偏移量。设定一个阈值(比如向下滚动超过100pt),当达到这个阈值时触发收缩动画,向上滚动回到阈值内时触发展开动画。这里要加个状态标记(比如isAnimating),避免动画反复触发。实现Liquid Glass的平滑动画
用UIViewPropertyAnimator来做弹性动画(dampingRatio设为0.8左右,接近Apple的流畅感),核心动画分两部分:- 悬浮栏的流动:修改它的顶部约束,让它平滑移动到Tab Bar的位置,同时可以微调模糊程度或者透明度,增强融合感。
- 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




