UINavigationBar在滚动时改变透明度

时间:2014-12-22 17:10:34

标签: ios uitableview uinavigationbar

我正在尝试实施UINavigationBar,在滚动UITableView时更改其透明度。开始时,导航栏应该具有透明背景,因此其下方的内容应该是可见的(将显示一个图像,例如我使用的是纯色):

Example 1

当用户滚动表格视图时,透明度应替换为纯色:

Example 2

表视图将包含节标题,这些标题应该与使用非半透明导航栏时相同。一旦从底部“触摸”它,标题视图应“粘贴”到导航栏:

Example 3

我试图在iOS应用程序中实现此流程没有运气。

对于初始状态,我将UINavigationBar translucent属性设置为YES,将backgroundColorbarTintColor设置为清除颜色,这给了我什么我想要。

然后,当用户滚动表视图时,我将backgroundColorbarTintColor更新为具有给定alpha分量的颜色,基于当前滚动偏移计算。我正在使用scrollViewDidScroll:协议中的UIScrollViewDelegate来执行此操作。但是,它仅更改导航栏的背景,使状态栏背景保持透明,这不是我想要的。

在没有将UINavigationBar属性设置为translucent的情况下,我无法找到另一种方式使YES透明。不幸的是,这会改变滚动时节标题的行为方式。由于导航栏是半透明的,当它们应该像“上面的第三个屏幕截图”一样“粘贴”到栏上时,部分标题视图隐藏在它下方。

我将不胜感激任何帮助,并提示如何在Objective-C或Swift中实现类似描述或类似的导航栏。

3 个答案:

答案 0 :(得分:1)

假设您有一个对tableView上方视图的引用,并且您不想在其中进行任何交互:

var overlayView:UIView!
var offsetDenominator:CGFloat!
let TARGER_COLOR = UIColor.blackColor()

override func viewDidLoad() {
    super.viewDidLoad()

    if let navCtrl = self.navigationController {
        self.offsetDenominator = headerView.frame.size.height - navCtrl.navigationBar.frame.height

        let targetCIColor = CIColor(CGColor: self.TARGER_COLOR.CGColor)
        let overlayColor = UIColor(red: targetCIColor.red, green: targetCIColor.green, blue: targetCIColor.blue, alpha: 0.0)

        self.overlayView = UIView(frame: self.headerView.frame)
        self.overlayView.backgroundColor = overlayColor

        self.view.addSubview(self.overlayView)
    }

...

override func scrollViewDidScroll(scrollView: UIScrollView) {
    if let navCtrl = self.navigationController, let breakpoint = offsetDenominator {
        let alpha = scrollView.contentOffset.y / breakpoint

        if alpha >= 1.0  {
            navCtrl.navigationBar.backgroundColor = self.TARGER_COLOR
        } else {
            let targetCIColor = CIColor(CGColor: self.TARGER_COLOR.CGColor)
            let overlayColor = UIColor(red: targetCIColor.red, green: targetCIColor.green, blue: targetCIColor.blue, alpha: alpha)

            self.overlayView.backgroundColor = overlayColor
            navCtrl.navigationBar.backgroundColor = UIColor.clearColor()
        }
    }
}

答案 1 :(得分:1)

我的方法是:

override func viewDidLoad() {
    super.viewDidLoad()
    ...
    self.setNavbarTransculent()
}

private func setNavbarTransculent() {
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
    self.navigationController?.navigationBar.isTranslucent = true
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let denominator: CGFloat = 50 //your offset treshold
    let alpha = min(1, scrollView.contentOffset.y / denominator)
    self.setNavbar(backgroundColorAlpha: alpha)
}

private func setNavbar(backgroundColorAlpha alpha: CGFloat) {
    let newColor = UIColor(red: 1, green: 1, blue: 1, alpha: alpha) //your color
    self.navigationController?.navigationBar.backgroundColor = newColor
    UIApplication.shared.statusView?.backgroundColor = newColor
}

extension UIApplication {
    var statusView: UIView? {
        return value(forKey: "statusBar") as? UIView
    }
}

答案 2 :(得分:-1)

<强> Swift3

var navAlpha = // Your appropriate calculation   
self.navigationController!.navigationBar.backgroundColor =  UIColor.red.withAlphaComponent(navAlpha)