2017-02-22 3 views
3

Подобно тому, что приложение Spotify или Apple Music делает, когда песня играет, он помещает настраиваемое представление на вершине UITabBar: enter image description hereПосмотреть на вершине UITabBar

Solutions Я пробовал:

  1. UITabBarController в ViewController с максимальным размером Container View, и пользовательский вид на верхней части контейнера View49pt над нижней направляющей Компоновка: enter image description here Проблема: Любое содержание в ViewControllers эм сложенные в UITabBarController, ограниченные снизу, не отображаются, потому что они скрыты за пользовательским макетом. Я пробовал переопределить size forChildContentContainer в UITabBarController, попробовал обновить нижний макет руководства, Nothing. Мне нужно изменить размер рамки контейнера в UITabBarController.

  2. Пробовал # 1 раз, но пытался решить проблему содержания прячась за него increasing the size of UITabBar, а затем с помощью ImageInset on every TabBarItem, чтобы привести его вниз, и добавив свой собственный вид сверху UITabBar. Не работает очень хорошо. Будут случаи, когда я хочу скрыть свой пользовательский вид.

  3. UITabBarController как корень, с каждыми детьми будучи ViewController с контейнером View + мое настраиваемым представлением: enter image description here Но теперь у меня есть несколько экземпляров моего настраиваемого представления с плавающими вокруг. Если я хочу изменить ярлык на нем, измените его на все виды. Или скрыть и т. Д.

  4. Переопределите свойство UITabBar UITabBarController и верните мой пользовательский UITabBar (завышенный его с помощью xib), у которого есть пользовательский вид UITabBar +. Проблема: Возможно, самая неприятная попытка для всех. Если вы переопределите это свойство с экземпляром class MyCustomTabBar : UITabBar {}, никакая вкладка не появится! И да, я установил делегат от myCustomTabBar до self.

Опираясь на # 3, но ищет лучшее решение.

+0

# 3 определенно работа, лучшее решение должно быть там. –

+0

@ Азизи Джавед вы можете добавить View на UINavigationController – aircraft

+0

@aircraft можете ли вы опубликовать пример того, что вы имеете в виду? Потому что проблема рассказать детям о контролерах их ограниченного кадра все еще существует. –

ответ

2

Ваша идея поместить его в диспетчер представлений для обложек хороша, но это вызовет только накладные расходы (большее количество диспетчеров просмотра будет загружено в память) и проблемы, когда вы захотите позже изменить код. Если вы хотите, чтобы панель всегда показывалась на вашем UITabBarController, вы должны добавить ее туда.

Вы должны подкласса UITabBarController и загрузить пользовательскую панель из наконечника. Там у вас будет доступ к вкладке (чтобы вы могли правильно расположить планку над ней), и вы будете загружать ее только один раз (что решает вашу проблему, с которой вы столкнетесь с другой панелью на каждой вкладке).

Что касается ваших просмотров, не реагирующих на размер настраиваемой панели, я не знаю, как вы можете это сделать, но мое лучшее предложение - использовать общедоступную переменную и уведомления, которые вы слушаете на своих отдельных вкладках.
Затем вы можете использовать это, чтобы изменить нижнее ограничение.

+0

Я могу загрузить пользовательский вид из nib в UITabBarController, но тогда как бы я его отобразил? Как-то показать UITabBarController? (это было бы идеально), или каждый из них будет отображать его, как показано в № 3? –

+0

Подкласс UITabBarController и загрузите его там с помощью 'nib'. Затем вы можете добавить его в 'view' и ограничить его кодом в верхней части вкладки. Вы можете ограничить его фиксированными 49 пикселями (высота вкладки) или использовать расположение панели. – vrwim

+0

Ах, правильно. Но тогда проблема детского просмотра контроллеров, расширяющаяся под пользовательским представлением ... Я мог бы поместить контейнерный вид между TabBarController и его дочерними элементами, чтобы ограничить размер, аналогичный # 3, но показать пользовательский вид в TabBarController. –

4

Я понял!

enter image description here

В сущности, я увеличил размер исходного UITabBar для размещения пользовательского представления (и уменьшения рамки вышеуказанных viewcontrollers), а затем добавляет дубликат UITabBar + пользовательский вид прямо на вершине Это.

Вот мясо того, что я должен был сделать. Я загрузил функционирующий пример этого и может быть found in this repo:

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 
    } 
} 
+0

Хорошее решение, однако это сломано при повороте устройства. –

1

Помимо игры с UITabBar или контейнера ВХ, вы могли бы также рассмотреть вопрос о включении вида в App Делегат главного окна, как в следующем сообщении:

View floating above all ViewControllers

Поскольку ваше представление все вокруг вместе с панелью вкладок, вполне нормально это сделать в App Delegate.

Вы всегда можете получить доступ к плавающему виду из приложения Delegate Singleton, сделав его собственностью делегата приложения. Легко контролировать его видимость в любом месте вашего кода.

Изменение константы ограничений между плавающим видом и окном супер-просмотра может регулировать положение вида, таким образом, красиво реагировать на изменения ориентации.

Другой (аналогичный) подход - сделать плавающее представление еще одним окном, как кнопка uid.

0

Это на самом деле очень просто, если вы подклассифицируете 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 
    } 
} 
Смежные вопросы