首页 文章

UINavigationBar颜色和透明之间的过渡 - bug [iOS 11]

提问于
浏览
3

当我按 UIViewController 并将 UINavigationBar 颜色更改为透明时,我在iOS 11上发现了一种奇怪的行为 . 重要的是我正在使用 largeTitles .

  • 我想将导航栏的红色更改为透明,这样可以正常工作 .

  • 但是,如果我点击backButton,再次禁用透明样式和红色样式 . ViewController上的NavigationBar不是红色但仍然是透明的 .

  • 由于@Menoor Ranpura建议我添加另一行,它在 UIViewController 中也设置了一个 backgroundColor 视图 - 当你在 UINavigationBar 上设置相同的颜色时这是很好的解决方法 . 但是,这不是问题的解决方案,因为导航栏的大部分仍然是透明的 . 为背景设置不同的颜色时可以看到它 . 例如,我设置了黄色 . 你可以在这里看到这个例子:

enter image description here

问题

prefersLargeTitles 设置为 true 时,如何正确地将导航栏颜色 from transparent 更改为 red again

代码

class ExampleTableTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "reuseID")
        navigationController?.navigationBar.redNavigationBar()
        title = "Red NavBar"
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        view.backgroundColor = .yellow
        navigationController?.navigationBar.redNavigationBar()
    }
}

 //Transparent Navigation bar controller
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Transparent NavBar"
        view.backgroundColor = .blue
        self.navigationController?.navigationBar.prefersLargeTitles = true
    }

    override func viewWillAppear(_ animated: Bool) {
        self.navigationController?.navigationBar.transparentNavigationBar()
    }

}
extension UINavigationBar {
    func redNavigationBar() {
        setBackgroundImage(nil, for: .default)
        shadowImage = nil


        prefersLargeTitles = true
        tintColor = .white
        largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
        titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
        barTintColor = .red
    }

    func transparentNavigationBar() {
        setBackgroundImage(UIImage(), for: .default)
        shadowImage = UIImage()
    }
}

我已经测试过的一些提示:

  • prefersLargeTitles 设置为 false 时,一切正常

  • prefersLargeTitles 设置为 true 时,一切正常,但 navigationBar 更改介于非透明颜色之间 . 例如,如果在绿色< - >黄色之间切换

  • 我不想在视图上设置 backgroundColor . 这不是一个解决方案,而是一种解决方法 .

在这里,您可以看到XCode的屏幕:

enter image description here

有趣的事实是,有一种叫做的东西: _UINavigationBarLargeTitleView 是透明的 . How to access it?

相关问题:

You can find example project here: https://github.com/kamwysoc/LargeTitlesNavigationBarTransition


更新提到@Menoor Ranpura答案

@Menoor Ranpura建议的代码是一种解决方法 . 这不是像 UINavigationBar 那样在 UIViewController 视图上设置相同 backgroundColor 的解决方案 . 但是,我更进一步,我改变了与 UINavigationBar 控制器不同的颜色 . 正如您在上面的gif上看到的那样,当 largeTitle 出现时,导航栏变为黄色 - 这意味着它是透明的 - 因为我们能够看到黄色的视图背景 .

2 回答

  • 0

    viewWillAppear 中致电 greenNavigationBar()

    override func viewWillAppear(_ animated: Bool)
    {
        view.backgroundColor = .red // this is kind of a workaround, However if you set color which will be different that `UINavigationBar` color you see that `largeTitle` is transparent because it shows a `backgroundColor` of a ViewController view.
        navigationController?.navigationBar.greenNavigationBar()
        title = "Green Title"
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(showTransparentViewController))
    }
    
  • 1

    这是你如何访问 _UINavigationBarLargeTitleView . 我认为你应该提交一个雷达,如果你还没有,因为设置背景颜色这个私人ivar只是一个黑客,而且仍然存在问题 .

    迅捷3/4:

    if let navigationBar = navigationController?.navigationBar,
        let titleView = navigationBar.subviews.first(where: {type(of: $0) == NSClassFromString("_UINavigationBarLargeTitleView")}) {
    
    }
    

    Objective-C的:

    __block UIView *titleView;
    
    [navigationController.navigationBar.subviews enumerateObjectsUsingBlock:^(UIView *subview, NSUInteger index, BOOL *stop) {
        Class _UINavigationBarLargeTitleView = NSClassFromString(@"_UINavigationBarLargeTitleView");
        if ([subview isKindOfClass:_UINavigationBarLargeTitleView]) {
            titleView = subview;
            *stop = YES;
        }
    }];
    

相关问题