iOS如何实现初始隐藏导航栏、滚动时显示的效果
嘿,我正好折腾过这种反向的导航栏滚动效果——初始隐藏,滚动时才滑出来,和Design+Code那个动画完全一致!下面分Web和iOS两种场景给你具体实现方案,你按需挑就行~
Web端实现方案
1. HTML结构
先搭个基础结构,导航栏加长内容区:
<nav class="navbar">Design+Code 风格导航栏</nav> <main class="content"> <!-- 这里放足够长的内容,比如重复的段落,用来测试滚动 --> <p>测试内容...</p> <p>测试内容...</p> <!-- 重复N次直到内容超出视口 --> </main>
2. CSS样式
核心是初始状态用transform把导航栏移出视口,加上过渡动画保证丝滑:
.navbar { position: fixed; top: 0; width: 100%; height: 60px; background: #ffffff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 初始隐藏:向上移出视口 */ transform: translateY(-100%); /* 过渡动画,控制动画时长和曲线 */ transition: transform 0.3s ease-out; z-index: 100; /* 确保导航栏在最上层 */ } .content { padding-top: 20px; /* 避免导航栏显示后遮挡内容顶部 */ min-height: 2000px; /* 强制内容超出视口,触发滚动 */ }
3. JavaScript逻辑
监听滚动事件,判断滚动方向和位置,控制导航栏的显示/隐藏:
let lastScrollPosition = 0; const navbar = document.querySelector('.navbar'); window.addEventListener('scroll', () => { const currentScrollPosition = window.pageYOffset || document.documentElement.scrollTop; // 规则:向下滚动超过50px时,显示导航栏 // 如果需要向上滚动时隐藏,可以取消下面的else分支注释 if (currentScrollPosition > 50 && currentScrollPosition > lastScrollPosition) { navbar.style.transform = 'translateY(0)'; } // else if (currentScrollPosition < lastScrollPosition) { // navbar.style.transform = 'translateY(-100%)'; // } lastScrollPosition = currentScrollPosition; });
iOS端实现方案(Swift UIKit)
如果你是做iOS应用,这里用UIKit实现和Design+Code完全一致的效果:
import UIKit class MainViewController: UIViewController { // 计算导航栏总高度(导航栏+状态栏) private let navbarTotalHeight = UINavigationController().navigationBar.frame.height + UIApplication.shared.statusBarFrame.height // 记录上次滚动的Y坐标 private var lastScrollY: CGFloat = 0 override func viewDidLoad() { super.viewDidLoad() setupUI() } private func setupUI() { // 初始状态隐藏导航栏:向上移出屏幕 navigationController?.navigationBar.transform = CGAffineTransform(translationX: 0, y: -navbarTotalHeight) // 创建滚动视图(如果是UITableView/UICollectionView,逻辑完全一致) let scrollView = UIScrollView(frame: view.bounds) scrollView.contentSize = CGSize(width: view.bounds.width, height: 2000) scrollView.backgroundColor = .systemGray6 scrollView.delegate = self view.addSubview(scrollView) } } extension MainViewController: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { let currentScrollY = scrollView.contentOffset.y // 向下滚动超过50pt时,动画显示导航栏 if currentScrollY > 50 && currentScrollY > lastScrollY { UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut) { self.navigationController?.navigationBar.transform = .identity } } // 向上滚动时隐藏导航栏(可选,根据需求调整) // else if currentScrollY < lastScrollY { // UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut) { // self.navigationController?.navigationBar.transform = CGAffineTransform(translationX: 0, y: -self.navbarTotalHeight) // } // } lastScrollY = currentScrollY } }
几个优化小技巧
- 添加滚动阈值:比如设置滚动超过50px才触发动画,避免轻微滚动导致导航栏频繁跳动
- 防抖处理:Web端可以给滚动事件加防抖函数,减少性能消耗(比如用
setTimeout控制触发频率) - 适配状态栏:iOS端注意动态计算状态栏高度,适配刘海屏等不同设备
- 动画曲线:用
ease-out曲线让动画更自然,符合Design+Code的流畅感
内容的提问来源于stack exchange,提问作者madone11
相关产品推荐
相关产品推荐

