PreferredStatusBarUpdateAnimation игнорируется

У меня есть AuthViewController, который представляет MainViewController следующим образом:

let mainVC = MainViewContoller()
mainVC.modalTransitionStyle = .CrossDissolve
authVC.presentViewController(mainVC, animated: true, completion: nil)

Я хочу, чтобы AuthViewController скрывал строку состояния, а MainViewController - так:

AuthViewController {

    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return .LightContent
    }

    override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
        return .Fade
    }

    override func prefersStatusBarHidden() -> Bool {
        return false
    }
}

MainViewController {

    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return .LightContent
    }

    override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
        return .Fade
    }

    override func prefersStatusBarHidden() -> Bool {
        return false
    }
}

Появится строка состояния, однако переопределение preferredStatusBarUpdateAnimation() игнорируется. Строка состояния отображается без анимации.

Мне удалось получить анимацию, установив prefersStatusBarHidden на MainViewController на true до viewDidAppear, а затем вызывая это:

UIView.animateWithDuration(0.3) {
    self.setNeedsStatusBarAppearanceUpdate()
}

Я не хочу называть это каждый раз. Что я делаю неправильно?

Ответ 1

тоже искал решение. Однако, похоже, у вас уже есть половина решения. Вы должны настроить переопределения для переменных, но для меня лучше всего было создать пару частных переменных для каждого из переопределений, и каждая переопределяющая функция возвращает ему соответствующую приватную переменную (см. Ниже). Затем вы измените личные переменные и вызовите setNeedsStatusBarAppearanceUpdate.

Кроме того, вам нужно установить View controller-based status bar appearance в info.plist на YES. В противном случае он будет по-прежнему полагаться на устаревшие методы UIApplication.shared....

Вот фрагмент:

override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
    get {
        return .slide
    }
}

private var statusBarStyle : UIStatusBarStyle = .default

override var preferredStatusBarStyle: UIStatusBarStyle {
    get {
        return statusBarStyle
    }
}

private var statusBarStatus : Bool = false

override var prefersStatusBarHidden: Bool {
    get {
        return statusBarStatus
    }
}

который я тогда мог бы вызвать в такой функции: (это один из моих примеров, поэтому не обращайте внимания на пользовательскую функцию).

func sliderView(sliderView: SliderView, didSlideToPlace: CGFloat, within: CGFloat) {

    let val = (within - (didSlideToPlace - sliderView.upCent))/(within)
    print(val)
    //Where you would change the private variable for the color, for example.
    if val > 0.5 {
        statusBarStyle = .lightContent
    } else {
        statusBarStyle = .default
    }
    UIView.animate(withDuration: 0.5, animations: {
        sliderView.top.backgroundColor = UIColor.black.withAlphaComponent(val)
        self.coverLayer.alpha = val
        self.scroll.backgroundColor = colors.lightBlueMainColor.withAlphaComponent(val)
    }, completion: {
        value in
        //If you do not call setNeedsStatusBarAppearanceUpdate() in an animation block, the animation variable won't be called it seems.
        UIView.animate(withDuration: 0.4, animations: {

            self.animating = true

            //Where you set the status for the bar (your part of the solution)
            self.statusBarStatus = false

            //Then you call for the refresh
            self.setNeedsStatusBarAppearanceUpdate()
        })
    })
}

В конечном итоге вам нужно настроить каждый контроллер представлений, но похоже, что вы хотите это сделать, поэтому надейтесь, что это поможет!