【问题标题】:Swift iOS -SplitViewController Won't Let Me Hide StatusBar?Swift iOS -SplitViewController 不会让我隐藏状态栏?
【发布时间】:2017-09-17 19:10:40
【问题描述】:

我按照本教程顺利隐藏了状态栏smoothly hide statusBar,当我在练习项目中使用它时一切正常。我在其他项目中使用没有SplitVC但有一个tabBar并使用navVC & tableView的代码,一切正常。在那些我可以成功地让它出现/消失。

在我的实际项目中,我使用的是用于 iPad 的 SplitViewController。我注意到当我实现从链接到我的 SplitViewController 的方向时,状态栏不会隐藏。然后,我使用 Apple 的默认 MasterDetailApp 制作了一个新项目,以确保我没有做错任何事情,但它在那里也不起作用。我保留了所有 Apple 的原始代码,只添加了使状态栏出现/消失的必要方法

  1. 在info.plist 中我添加了View controller-based status bar appearance 并将其设置为YES

  2. 在情节提要中,我向 DetailVC 添加了一个紫色按钮以触发 statusBar 消失。我还在方法中添加了让backBar按钮消失/重新出现

  3. 我在 DetailVC 场景中添加了使 statusBar 消失/消失的所有方法。

  4. 我在场景中添加了一个 tapGesture 以使 statusBar 和 backButton 重新出现

我点击了主场景上的加号按钮,出现了一个日期,点击它进入 DetailVC,按下紫色buttonPressed 隐藏状态栏和后退按钮,但只有后退按钮被隐藏。我触摸背景,backButton 重新出现。状态栏不动。

我保留了 Apple 项目的所有原始代码,并在其下方添加了我的代码:

class DetailViewController: UIViewController {

    //MARK:-  Apple's code
    @IBOutlet weak var detailDescriptionLabel: UILabel!

    func configureView() {
        if let detail = detailItem {
            if let label = detailDescriptionLabel {
                label.text = detail.description
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        configureView()

        // make backButton and statusBar reappear when scene is tapped
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(showBackButtonAndStatusBar))
        view.addGestureRecognizer(tapGesture)
    }

    var detailItem: NSDate? {
        didSet {
            configureView()
        }
    }

    //MARK:- Outside of the tapGesture in viewDidLoad everything below here is what I added

    // bool to determine wether to hide the statusBar or not
    var statusBarShouldBeHidden = false

    // api method to allow the staus bar to be hidden
    override var prefersStatusBarHidden: Bool{
        return statusBarShouldBeHidden
    }

    // api method to animate status bar appearance/disappearance
    override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation{
        return .slide
    }

    @IBAction func buttonTapped(_ sender: UIButton) {

        // 1. hide backBar button
        navigationItem.setHidesBackButton(true, animated: false)

        // 2. set bool to true
        statusBarShouldBeHidden = true

        UIView.animate(withDuration: 0.25){
            // 3. api method to allow the statusBar to disappear
            self.setNeedsStatusBarAppearanceUpdate()
        }
    }

    //called when background is touched and added to tapGesture in viewDidLoad
    @objc func showBackButtonAndStatusBar(){

        // 1. set bool to false
        statusBarShouldBeHidden = false

        UIView.animate(withDuration: 0.25){
            // 2. bring statusBar back
            self.setNeedsStatusBarAppearanceUpdate()
        }

        // 3. bring backButton back
        navigationItem.setHidesBackButton(false, animated: true)
    }
}

如何让 SplitViewVC 让我隐藏状态栏?

【问题讨论】:

  • 有趣,但是设置应用程序(原生)可以隐藏它,所以我们也可以。
  • 你解决了吗?
  • @Jageen 我真的厌倦了它,只是决定保留状态栏。在我的 iOS 时间里,SplitViewController 必须是所有头痛中最头疼的问题。我对自己说,也许我必须在 SplitViewController 本身上更改它,但问题是它会将应用程序广泛应用于连接到 splitVC 的每个子 vc。那是我说“呃,算了吧”
  • 不错的选择,你可以在这里写你的研究,看看是否有人会想出不同的方法(只有当你正在寻求解决方案时,否则只需删除这个问题:))
  • @Jageen 我可能会回到它。我还有很多其他的错误需要解决,这就是我决定继续前进的原因。我确信其他人会遇到这个问题,而没有意识到是 splitVC 导致了这个问题。谢谢你的convo ????????????

标签: ios swift uisplitviewcontroller statusbar master-detail


【解决方案1】:

您似乎正试图通过详细视图控制器隐藏状态栏。用户界面中的状态栏仅由拆分视图控制器控制,因为它位于视图控制器层次结构的顶部。因此,控制状态栏行为的最简单方法是继承 UISplitViewController,然后覆盖子类中的 prefersStatusBarHidden 计算属性。此外,请确保您转到您的故事板并将身份检查器中拆分视图控制器的自定义类字段更改为您的子类。

---更新的答案--- @LanceSamaria 好的,我把你的代码放在上面并调整了一些东西。首先,我只添加了按钮动作而不是点击手势。另外,我注释掉了隐藏后退按钮,因为这在 UI 中很重要,以便能够返回到主视图。无论如何,现在当您单击按钮时,SplitViewController 将隐藏状态栏。如果再次单击该按钮,则状态栏将重新出现。

导入 UIKit

类 DetailViewController: UIViewController {

@IBOutlet weak var detailDescriptionLabel: UILabel!

var statusBarShouldBeHidden = false

func configureView() {
    // Update the user interface for the detail item.
    if let detail = self.detailItem {
        if let label = self.detailDescriptionLabel {
            label.text = detail.description
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.configureView()
}

/* override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation{
    return .slide
} */


var detailItem: NSDate? {
    didSet {
        // Update the view.
        self.configureView()
    }
}

@IBAction func buttonTapped(_ sender: UIButton) {
    // 1. hide backBar button
    //navigationItem.setHidesBackButton(true, animated: false)

    // 2. set bool to true
    statusBarShouldBeHidden = !statusBarShouldBeHidden

    UIView.animate(withDuration: 0.25){
        // 3. api method to allow the statusBar to disappear
        guard let svc = self.splitViewController as? SplitViewController else { return }
        svc.statusBarShouldBeHidden = self.statusBarShouldBeHidden
        svc.setNeedsStatusBarAppearanceUpdate()
    }
}

}

另外,还有一件非常重要的事情。下面是我的拆分视图控制器子类的代码。请注意,我在拆分视图控制器和细节控制器中都使用了相同的变量名称“statusBarShouldBeHidden”。

导入 UIKit

类SplitViewController:UISplitViewController {

var statusBarShouldBeHidden = false

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

override var prefersStatusBarHidden: Bool {
    return statusBarShouldBeHidden
}

}

感谢您发布此问题。这帮助我学到了很多东西,试图解决这个问题。如果您对此仍有疑问,请告诉我。

【讨论】:

  • 感谢您的回答。我实际上已经考虑过您提出的建议,但后来我意识到连接到 splitVC 的每个 vc 都会删除我不想要的状态栏。在那之后我认输并决定保留状态栏。 SplitVC 是一个令人头疼的问题。我已经将所有内容进行了子类化和连接。在我完成所有其他我一直遇到的错误后,我会回到它。我会支持你,因为我认为你的答案是正确的,只要有人希望每个子 vc 都删除状态栏
  • @LanceSamaria 嗨,我不知道堆栈溢出是否会通知你我更新的答案,所以我评论你让你知道。
  • 我查看了您的答案,您必须在顶视图控制器中更改它是正确的。我有一个子 vc,隐藏状态栏的唯一方法是将其隐藏在其父 vc (navVC) 中。我会接受你的答案作为接受的答案!谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-20
  • 2023-04-04
  • 2015-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多