利用 UIScrollViewDelegate 兩個方法記錄上一次 contentOffset.y,比較當前位移決定方向:
contentOffset.y **增加** → 隱藏導航列。contentOffset.y **減少** → 顯示導航列。@interface ViewController ()
@property (assign) CGFloat lastContentOffset;
@end
@implementation ViewController
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
self.lastContentOffset = scrollView.contentOffset.y;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat currentOffset = scrollView.contentOffset.y;
if (currentOffset < self.lastContentOffset) {
// 向下滑
[self.navigationController setNavigationBarHidden:NO animated:YES];
} else if (currentOffset > self.lastContentOffset) {
// 向上滑
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
// 可選:更新 lastContentOffset 以便連續判斷
// self.lastContentOffset = currentOffset;
}
@end
fabs(currentOffset - lastContentOffset) < 5 不處理)。contentOffset.y <= 0 時強制顯示;接近底部時可選擇不隱藏。scrollViewDidEndDragging:willDecelerate: 在拖拽結束時修正狀態,避免慣性滑動導致閃爍。UINavigationBarAppearance 配合 prefersLargeTitles 時,隱藏/顯示動畫行為不同,需實測調整。var lastContentOffset: CGFloat = 0
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
lastContentOffset = scrollView.contentOffset.y
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let currentOffset = scrollView.contentOffset.y
let delta = currentOffset - lastContentOffset
guard abs(delta) > 5 else { return } // 忽略抖動
navigationController?.setNavigationBarHidden(delta > 0, animated: true)
}