web-dev-qa-db-ja.com

UITabBarの上に表示

SpotifyまたはAppleミュージックアプリが曲の再生中に行うことと同様に、カスタムビューをUITabBarの上に配置します: enter image description here

私が試したソリューション:

  1. 最大サイズのコンテナービューを備えたViewControllerのUITabBarController、およびコンテナービューの上にあるカスタムビュー49pt下のレイアウトガイドの上: enter image description here問題:下部に制約されたUITabBarControllerに埋め込まれたViewControllersのコンテンツは、カスタムレイアウトの背後に隠れているため表示されません。私はUITabBarControllerでsize forChildContentContainerをオーバーライドしてみました。下部のレイアウトガイドNothingを更新してみました。 UITabBarControllerのコンテナビューのフレームのサイズを変更する必要があります。

  2. もう一度#1を試しましたが、コンテンツの背後に隠れている問題を ITabBarのサイズを増やす で解決し、次に すべてのTabBarItemのImageInset を使用してそれを停止し、追加しましたUITabBarの上にあるカスタムビュー。本当にうまくいきませんでした。カスタムビューを非表示にしたい場合があります。

  3. ルートとしてのUITabBarController、各子はコンテナビュー+私の​​カスタムビューを持つViewController: enter image description here しかし、今では、カスタムビューの複数のインスタンスが浮かんでいます。ラベルを変更したい場合は、すべてのビューに変更する必要があります。または非表示など.

  4. UITabBarControllerのUITabBarプロパティをオーバーライドし、UITabBar +カスタムビューを持つカスタムUITabBar(xibでインフレートされた)を返します。 問題:おそらくすべての中で最もイライラする試み。そのプロパティをclass MyCustomTabBar : UITabBar {}のインスタンスでオーバーライドすると、タブは表示されません!そして、はい、myCustomTabBarのデリゲートをselfに設定しました。

#3に傾いているが、より良いソリューションを探している。

12
Aziz Javed

わかった!

enter image description here

基本的に、元のUITabBarのサイズを大きくしてカスタムビューに対応し(そして上記のビューコントローラーのフレームを縮小し)、その上に複製の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
    }
}
8
Aziz Javed

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
  }
}
6
noobular

ラッパービューコントローラーに配置するという考えは良いですが、オーバーヘッド(ビューコントローラーがメモリに読み込まれる)が増えるだけで、後でコードを変更するときに問題が発生します。バーを常にUITabBarControllerに表示したい場合は、そこに追加する必要があります。

UITabBarControllerをサブクラス化し、nibからカスタムバーをロードする必要があります。そこでタブバーにアクセスでき(その上にバーを正しく配置できます)、一度にロードするだけです(これにより、各タブに別のバーがあることに直面するという問題が解決されます)。

カスタムバーのサイズに反応しないビューについては、どうすればよいかわかりませんが、個々のタブでリッスンするパブリック変数と通知を使用することをお勧めします。
それを使用して、下部拘束を変更できます。

2
vrwim

UITabBarまたはコンテナーvcで遊ぶ以外に、次の投稿のように、アプリデリゲートのビューをメインウィンドウに追加することも検討できます。

すべてのViewControllerの上にフローティングビュー

あなたのビューはタブバーと一緒に四方八方にあるので、アプリデリゲートでそれを作ることは全く問題ありません。

アプリデリゲートのプロパティにすると、アプリデリゲートシングルトンからフローティングビューにいつでもアクセスできます。コードの任意の場所で可視性を制御するのは簡単です。

フローティングビューとスーパービューウィンドウ間の制約の定数を変更すると、ビューの位置を調整できるため、向きの変化にスムーズに対応できます。

別の(類似した)アプローチは、フローティングビューをuidボタンのような別のウィンドウにすることです。

1
user8458999
  1. タブバーの高さでビューのフレームを作成し、上に移動します。2. set tabBar hiddenはtrueです。
0
Ning