Подтвердить что ты не робот

UINavigationBar, который изменяет прозрачность при прокрутке

Я пытаюсь реализовать UINavigationBar, который меняет свою прозрачность при прокрутке UITableView. Вначале навигационная панель должна иметь прозрачный фон, поэтому содержимое под ним должно быть видимым (появится изображение, для примера использую сплошной цвет):

Example 1

Когда пользователь прокручивает табличный вид, прозрачность должна быть заменена сплошным цветом:

Example 2

В представлении таблицы будут заголовки разделов, которые должны действовать как при использовании непрозрачной навигационной панели. Заголовки заголовков должны "прилипать" к панели навигации, как только они "касаются" ее снизу:

Example 3

Мне не повезло с попыткой реализовать этот поток в приложении iOS.

Для начального состояния я устанавливаю свойство UINavigationBar translucent на YES, и оба backgroundColor и barTintColor очищают цвет, что дает мне то, что я хочу.

Затем, когда пользователь прокручивает табличное представление, я обновляю backgroundColor и barTintColor до цвета с заданным альфа-компонентом, вычисленным на основе текущего смещения прокрутки. Для этого я использую протокол scrollViewDidScroll: из UIScrollViewDelegate. Тем не менее, он меняет только фон панели навигации, оставляя прозрачный фон состояния, что не то, что я хочу.

Я не могу найти другой способ сделать UINavigationBar прозрачным без установки свойства translucent в YES. К сожалению, это влияет на то, как заголовки разделов действуют при прокрутке. Поскольку панель навигации является полупрозрачной, просмотры заголовков разделов скрываются ниже нее, когда они должны "приклеиваться" к панели, как на третьем скриншоте выше.

Я был бы признателен за любую помощь и подсказки о том, как создать панель навигации, которая действует как описанная или подобная в Objective-C или Swift.

4b9b3361

Ответ 1

Предполагая, что у вас есть ссылка на представление выше таблицыView и что вы не хотите что-либо в нем взаимодействовать:

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()
        }
    }
}

Ответ 2

Мой подход:

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
    }
}

Ответ 3

Swift3

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