在UITabBar顶部查看

Azi*_*ved 10 uitabbar ios swift

与播放歌曲时Spotify或Apple Music应用程序的功能类似,它会在UITabBar上放置一个自定义视图: 在此输入图像描述

我试过的解决方案:

  1. 具有最大容器视图的ViewController中的UITabBarController,以及底部布局指南上方的Container View49pt顶部的自定义视图: 在此输入图像描述 问题:嵌入在底部的UITabBarController中的ViewControllers中的任何内容都不会显示,因为它们隐藏在自定义布局后面.我已经尝试覆盖size forChildContentContainerUITabBarController,尝试更新底部布局指南,Nothing.我需要调整UITabBarController的容器视图框架的大小.

  2. 再次尝试#1,但尝试通过增加UITabBar的大小来解决隐藏在其后面的内容问题,然后在每个TabBarItem上使用ImageInset将其关闭,并在UITabBar之上添加我的自定义视图.工作得不好.有时我想隐藏自定义视图.

  3. UITabBarController作为root,每个子节点都是一个ViewController,带有一个Container View +我的自定义视图: 在此输入图像描述 但现在我有多个自定义视图实例浮动.如果我想更改其上的标签,则必须将其更改为所有视图.或隐藏等

  4. 覆盖UITabBarController的UITabBar属性并返回我的自定义UITabBar(用xib充气),它有一个UITabBar +我的自定义视图.问题:可能是所有人最令人沮丧的尝试.如果使用实例覆盖该属性class MyCustomTabBar : UITabBar {},则不会显示任何选项卡!是的,我设定的委托myCustomTabBarself.

倾向于#3,但寻找更好的解决方案.

Azi*_*ved 8

我知道了!

在此输入图像描述

本质上,我增加了原始UITabBar的大小以容纳自定义视图(并缩小上面的viewcontrollers的框架),然后在它上面添加一个重复的UITabBar +自定义视图.

这是我必须要做的事情.我上传了一个功能正常的例子,可以在这个回购中找到:

class TabBarViewController: UITabBarController {

    var currentlyPlaying: CurrentlyPlayingView!
    static let maxHeight = 100
    static let minHeight = 49
    static var tabbarHeight = maxHeight

    override func viewDidLoad() {
        super.viewDidLoad()

        currentlyPlaying = CurrentlyPlayingView(copyFrom: tabBar)
        currentlyPlaying.tabBar.delegate = self

        view.addSubview(currentlyPlaying)
        tabBar.isHidden = true
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        currentlyPlaying.tabBar.items = tabBar.items
        currentlyPlaying.tabBar.selectedItem = tabBar.selectedItem
    }
    func hideCurrentlyPlaying() {
        TabBarViewController.tabbarHeight = TabBarViewController.minHeight
        UIView.animate(withDuration: 0.5, animations: {
            self.currentlyPlaying.hideCustomView()
            self.updateSelectedViewControllerLayout()
        })
    }
    func updateSelectedViewControllerLayout() {
        tabBar.sizeToFit()
        tabBar.sizeToFit()
        currentlyPlaying.sizeToFit()
        view.setNeedsLayout()
        view.layoutIfNeeded()
        viewControllers?[self.selectedIndex].view.setNeedsLayout()
        viewControllers?[self.selectedIndex].view.layoutIfNeeded()
    }
}

extension UITabBar {

    open override func sizeThatFits(_ size: CGSize) -> CGSize {
        var sizeThatFits = super.sizeThatFits(size)
        sizeThatFits.height = CGFloat(TabBarViewController.tabbarHeight)
        return sizeThatFits
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不错的解决方案,但是当您旋转设备时会损坏。 (3认同)

Tia*_*ida 7

从 iOS 11 开始,这变得更容易了。添加视图时,您可以执行以下操作:

viewControllers?.forEach {
   $0.additionalSafeAreaInsets = UIEdgeInsets(
      top: 0, 
      left: 0,
      bottom: yourView.height,
      right: 0
   )
}
Run Code Online (Sandbox Code Playgroud)

  • 恕我直言,你的回答确实被低估了。如果可以的话我完全会+2:) (2认同)

noo*_*lar 6

如果您继承UITabBarController并以编程方式添加视图,这实际上非常简单.使用此技术可自动支持标签栏的旋转和大小更改,无论您使用的是哪个版本.

class CustomTabBarController: UITabBarController {
  override func viewDidLoad() {
    super.viewDidLoad()

    //...do some of your custom setup work
    // add a container view above the tabBar
    let containerView = UIView()
    containerView.backgroundColor = .red
    view.addSubview(containerView)
    containerView.translatesAutoresizingMaskIntoConstraints = false
    containerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    containerView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true

    // anchor your view right above the tabBar
    containerView.bottomAnchor.constraint(equalTo: tabBar.topAnchor).isActive = true

    containerView.heightAnchor.constraint(equalToConstant: 50).isActive = true
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这不会在选项卡栏控制器内插入视图控制器,这是重点 (3认同)

vrw*_*wim 2

您将其放入包装视图控制器的想法很好,但它只会导致开销(更多视图控制器加载到内存中),并且当您稍后想要更改代码时会出现问题。如果您希望该栏始终显示在您的 上UITabBarController,那么您应该将其添加到那里。

您应该子类化UITabBarController并从笔尖加载自定义栏。在那里,您将可以访问选项卡栏(这样您就可以将栏正确地放置在其上方),并且您只需加载一次(这解决了您将面临的每个选项卡上都有不同栏的问题)。

至于您的视图对自定义栏的大小没有反应,我不知道如何做到这一点,但我最好的建议是使用公共变量和您在各个选项卡中收听的通知。
然后您可以使用它来更改底部约束。