Как мне включить слайд-аут / бургер меню в существующий контроллер панели вкладок - PullRequest
0 голосов
/ 15 октября 2018

Итак, я хочу создать слайд-меню.Я хочу, чтобы меню выдвигалось при касании элемента / кнопки панели вкладок.До сих пор я создал контроллер представления вкладок с 4 различными кнопками панели вкладок.Каждая кнопка приводит к отдельному контроллеру представления, и каждый контроллер представления был разделен на их собственную раскадровку.

Я предпринял попытку добавить UIViewController для бокового меню в класс, который уже установлен как UITabBarController, и яполучил ошибку:

Множественное наследование от классов 'UITabBarController' и 'UIViewController'.

Есть ли способ обойти это?

Я ценю всю помощь

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Приложения, как правило, имеют контейнер верхнего уровня, такой как Tab Bar Controller, который не может быть встроен в представление.Подход здесь заключается в том, чтобы обернуть основной корпус и левое меню внутри Container View.Теперь оба эти элемента могут быть расположены внутри оболочки View Controller.

Container Storyboard

A Scroll View используется для имитации открытия и закрытия меню с помощьюсдвиг левого меню в / вне экрана.

Содержащий контроллер вида

Перетащите View Controller на раскадровку.Это ваша точка входа в приложение.Установите флажок для Is Initial View Controller.Измените Simulated Size с Fixed на Freeform.Установите ширину 568, чтобы мы могли разместить меню и панель вкладок рядом друг с другом.Создайте новый файл Swift и установите для этого класса контроллера представления значение ContainerVC.

import UIKit
class ContainerVC : UIViewController {
}

Представление прокрутки

Внутри контроллера представления контейнера добавьте Scroll View и добавьте ограничения во всех направлениях.

Установите флажок для Scrolling Enabled.Это позволяет панорамировать экран, чтобы скользить по меню.Возможно, вам придется отключить это, если ваше приложение использует элементы горизонтальной прокрутки.

Установите флажок Paging Enabled.Это приводит меню в открытое или закрытое состояние.

Снимите флажок для Bounces.Вы не хотите прокручивать правый край контроллера панели вкладок.

Подключите IBOutlet к ContainerVC:

@IBOutlet weak var scrollView: UIScrollView!

Левый контейнер

Левый контейнерудерживает меню и не совсем на всю ширину экрана.

Перетащите Container View в левую часть Scroll View.

Добавьте ограничения сверху, слева иправо на содержащий Scroll View.

Жесткий код ширины до 260.

Добавьте ограничение для Equal height со встроенным представлением ContainerVC.Примечание: не ограничивайте высоту представлением прокрутки.Удалите встроенный View Controller, поставляемый с Container View.

. Перетащите новый Table View Controller (любой вид в соответствии с вашими потребностями) на раскадровку и подключитесь с помощью перехода.

Right Container

В правом контейнере содержится основная часть вашего приложения, а именно Tab Bar Controller.

Перетащите секунду Container View в правую часть Scroll View.

Добавить ограничения к содержащему Scroll View для верха, справа и низа.Подключите горизонтально к левому представлению контейнера, которое вы создали ранее.

Ограничьте Equal height и Equal width для встроенного просмотра ContainerVC.

Примечание: не ограничивайте их просмотром прокрутки.

setConstraintsFromContainers

Снова удалите встроенный View Controller, который поставляется вместе с Container View.Вместо этого создайте embed переход к Tab Bar Controller.

Чтобы создать небольшое визуальное разделение между двумя контейнерами, добавьте Runtime Attribute к Правильному контейнеру.Добавьте layer.shadowOpacity с числом 0.8.

Вкладки

Вставьте каждую вкладку в Navigation Controller.Это дает вам Navigation Bar.

. Перетащите Bar Button Item в верхний левый угол каждого Navigation Bar.

. Подключите IBAction к каждому контроллеру.Они вызовут Notification для прадеда ContainerVC для переключения меню.

@IBAction func toggleMenu(sender: AnyObject) {
  NotificationCenter.default().post(name: Notification.Name("toggleMenu"), object: nil)
}

Наконец добавьте следующий код в ContainerVC:

class ContainerVC : UIViewController {

    // This value matches the left menu's width in the Storyboard
    let leftMenuWidth:CGFloat = 260

    // Need a handle to the scrollView to open and close the menu
    @IBOutlet weak var scrollView: UIScrollView!

    override func viewDidLoad() {

        // Initially close menu programmatically.  This needs to be done on the main thread initially in order to work.
        DispatchQueue.main.async() {
            self.closeMenu(animated: false)
        }

        // Tab bar controller's child pages have a top-left button toggles the menu
        NotificationCenter.default.addObserver(self, selector: #selector(ContainerVC.toggleMenu), name: NSNotification.Name(rawValue: "toggleMenu"), object: nil)

        NotificationCenter.default.addObserver(self, selector: #selector(ContainerVC.closeMenuViaNotification), name: NSNotification.Name(rawValue: "closeMenuViaNotification"), object: nil)

        // Close the menu when the device rotates
        NotificationCenter.default.addObserver(self, selector: #selector(ContainerVC.rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)

        // LeftMenu sends openModalWindow
        NotificationCenter.default.addObserver(self, selector: #selector(ContainerVC.openModalWindow), name: NSNotification.Name(rawValue: "openModalWindow"), object: nil)

    }

    // Cleanup notifications added in viewDidLoad
    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @objc func openModalWindow() {
        performSegue(withIdentifier: "openModalWindow", sender: nil)
    }

    @objc func toggleMenu() {
        scrollView.contentOffset.x == 0  ? closeMenu() : openMenu()
    }

    // This wrapper function is necessary because closeMenu params do not match up with Notification
    @objc func closeMenuViaNotification(){
        closeMenu()
    }

    // Use scrollview content offset-x to slide the menu.
    func closeMenu(animated:Bool = true){
        scrollView.setContentOffset(CGPoint(x: leftMenuWidth, y: 0), animated: animated)
    }

    // Open is the natural state of the menu because of how the storyboard is setup.
    func openMenu(){
        print("opening menu")
        scrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
    }

    @objc func rotated(){
        if UIDeviceOrientationIsLandscape(UIDevice.current.orientation) {
            DispatchQueue.main.async() {
                print("closing menu on rotate")
                self.closeMenu()
            }
        }
    }
}

extension ContainerVC : UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("scrollView.contentOffset.x:: \(scrollView.contentOffset.x)")
    }

    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        scrollView.isPagingEnabled = true
    }

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        scrollView.isPagingEnabled = false
    }
}

Код завершенследующее:

  • Прослушивание уведомления "toggleMenu"
  • Реализация метода toggleMenu путем открытия или закрытия на основе текущего contentOffset.x
  • Открыть и закрытьизменив contentOffset-x.

Надеемся, у вас есть простое выпадающее меню слева для создания остальной части вашего приложения.

0 голосов
/ 16 октября 2018

Не используйте UITabBarController и управляйте вкладками, используя один контроллер вида и действия кнопок.

...