安全区域在自定义 TabBarController 的 ViewController 中不起作用

Posted

技术标签:

【中文标题】安全区域在自定义 TabBarController 的 ViewController 中不起作用【英文标题】:Safe area not working in custom TabBarController's ViewController 【发布时间】:2020-06-01 16:19:23 【问题描述】:

在我的应用 AppDelegate 的 didFinishLaunchingWithOptions 中,初始化 UIWindow 属性后,我将根控制器设置为 UITabBarController 的子类,在其中设置视图控制器(以及其他一些自定义行为)。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 

    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = TabBarController() // a subclass of UITabBarController
    self.window?.makeKeyAndVisible()

    return true

我遇到的问题是 TabBarController 的视图控制器中的安全区域似乎无法正常工作。

例如:将视图粘贴到视图控制器视图的底部,使用它的 safeAreaLayoutGuide,放在标签栏后面。

self.bottomView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor)

自定义行为(例如设置色调颜色、设置 viewControllers 及其标签栏项目,或设置 tabBarController 的代理 - 这里没什么疯狂的)设置是在 viewDidLoad 中进行的。

注意:我只在代码中工作,我不使用界面生成器。

【问题讨论】:

“我错过了什么” 是的,但我不知道它是什么,因为我无法重现您所描述的内容。在我的机器上,在 ios 13、iOS 12 或其他任何版本中,一个固定在标签栏控制器子级安全区域底部的子视图出现在标签栏上方,正如人们所期望的那样。 如果你想让你的视图坚持superview的底部,你不需要考虑safeAreaLayoutGuide,直接用view.bottomAnchor固定 @matt 我只是将视图添加到 viewDidLoad 中的超级视图中,然后在我的 UITabBarController 的 init 中的 viewControllers 属性中初始化视图控制器。我不觉得我在这里做任何奇怪的事情...... @GauravChandarana 通过将我的约束设置为 safeAreaLayoutGuide 的底部和视图的底部,我得到了完全相同的结果。 @GauravChandarana 你所说的一切都是假的。请停止误导 OP。 【参考方案1】:

问题在于我以编程方式呈现标签栏控制器的方式。 我在 AppDelegate 的 didFinishLaunchingWithOptions 中所做的是:

    self.window?.rootViewController = MyTabBarController()
    self.window?.makeKeyAndVisible()

我解决了将标签栏放在 NavigationController 中的问题:

    let navigationController = UINavigationController(rootViewController: MyTabBarController())
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()

【讨论】:

那没用。首先,问题中没有任何内容告诉我们您已将 UITabBarController 子类化(这绝不是一件好事)。其次,答案中没有任何内容可以解释您最初做错了什么。 我同意。我不知道我应该如何把这个问题变成“有用的”。我在回复您的第一条评论中提到了 UITabBarController。我可能会删除这个问题。 我不会反对,但追踪它会更有用。【参考方案2】:

无法复制。以下是项目中视图控制器的完整代码,该代码执行您似乎描述的操作:

class FirstViewController: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .red
        self.view.addSubview(v)
        v.widthAnchor.constraint(equalToConstant: 100).isActive = true
        v.heightAnchor.constraint(equalToConstant: 100).isActive = true
        v.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        v.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor).isActive = true
    

结果如下;红色方块恰好出现在我们期望看到的位置,固定在标签栏的顶部:

【讨论】:

以上是关于安全区域在自定义 TabBarController 的 ViewController 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在自定义 UIControl 对象中定义自定义触摸区域

如何在自定义帖子类型UI菜单图标区域添加字体真棒图标?

在自定义注解中使用 spring 安全表达式

该请求不包含在自定义过滤器中。春季安全

如何在自定义用户控件上创建单击事件?

强制在自定义 WPF 控件中重新绘制自定义绘制的 UIElement