Swift 导航栏滑动变色

在许多 iOS 应用中,我们经常可以看到导航栏会在滑动页面时发生颜色的变化。这样的设计可以增强用户体验,使用户在不同页面之间的切换更加流畅。本文将介绍如何使用 Swift 实现导航栏滑动变色效果。

1. 导航栏基本设置

在开始实现滑动变色效果之前,我们首先需要对导航栏进行一些基本的设置。在 ViewControllerviewDidLoad 方法中,我们可以通过以下代码进行设置:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 设置导航栏背景色
    navigationController?.navigationBar.barTintColor = UIColor.white
    
    // 设置导航栏标题颜色
    navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
    
    // 隐藏导航栏底部的分割线
    navigationController?.navigationBar.shadowImage = UIImage()
    navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
}

在上述代码中,我们通过 navigationBar.barTintColor 属性设置导航栏的背景色,通过 navigationBar.titleTextAttributes 属性设置导航栏标题的颜色。此外,我们还通过设置一张空的图片作为导航栏的背景图和阴影图,以隐藏底部的分割线。

2. 监听滑动事件

为了实现导航栏滑动变色效果,我们需要监听滑动事件,并根据滑动的偏移量来动态改变导航栏的颜色。

我们可以在 ViewController 中添加一个 UIScrollViewDelegate 的扩展,并实现 scrollViewDidScroll(_:) 方法来监听滑动事件:

extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offsetY = scrollView.contentOffset.y
        let maxOffsetY = scrollView.contentSize.height - scrollView.frame.height
        
        // 计算滑动的比例
        let progress = offsetY / maxOffsetY
        
        // 根据滑动比例改变导航栏颜色
        navigationController?.navigationBar.barTintColor = UIColor(red: 1, green: 1 - progress, blue: 1 - progress, alpha: 1)
    }
}

在上述代码中,我们首先通过 scrollView.contentOffset.y 获取当前滑动的偏移量,通过 scrollView.contentSize.heightscrollView.frame.height 计算滑动的比例。然后,我们根据滑动比例来改变导航栏的颜色,使其逐渐变浅。

3. 注册滑动事件

为了使滑动事件生效,我们还需要在 viewWillAppear(_:) 方法中注册滑动事件的监听器,并在 viewWillDisappear(_:) 方法中取消监听。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    // 注册滑动事件的监听器
    scrollView.delegate = self
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    // 取消滑动事件的监听器
    scrollView.delegate = nil
}

在上述代码中,我们通过将 scrollView.delegate 设置为 self 来注册滑动事件的监听器。在 viewWillDisappear(_:) 方法中,我们将 scrollView.delegate 设置为 nil 来取消监听。

4. 完整代码示例

以下是一个完整的示例代码:

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var scrollView: UIScrollView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 设置导航栏背景色
        navigationController?.navigationBar.barTintColor = UIColor.white
        
        // 设置导航栏标题颜色
        navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
        
        // 隐藏导航栏底部的分割线
        navigationController?.navigationBar.shadowImage = UIImage()
        navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // 注册滑动事件的监听器
        scrollView.delegate = self
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        // 取消滑动事件的监听器
        scrollView.delegate = nil
    }
}

extension ViewController: UIScrollViewDelegate {