Меню из панели вкладок в раскадровке

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

enter image description here

Есть ли какие-либо предложения по реализации этого? Заранее спасибо.

Ответ 1

Я бы рекомендовал вам это сделать:

Во-первых, вы должны думать обо всех типах вкладок, которые могут быть в панели вкладок. На снимке экрана есть вкладки, которые представляют собой контроллер и вкладку, в которой представлено меню. Таким образом, мы могли бы создать перечисление со всеми этими типами:

enum TabType {
    case controller
    case menu
}

После этого вы можете сохранить массив типов вкладок, чтобы они отображались в панели вкладок, для вашего скриншота

let tabTypes: [TabType] = [.controller, .controller, .controller, .controller, .menu]

Затем вы должны реализовать UITabBarControllerDelegate func tabBarController(_:, shouldSelect:) → Bool метод func tabBarController(_:, shouldSelect:) → Bool, который возвращает true если полосе вкладок разрешено выбирать переданный контроллер, а false противном случае.

Если вы вернете true чем всякая другая работа (например, представление диспетчера представлений и других вещей), контроллер панели вкладок сделает для вас.

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

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    if let index = tabBarController.viewControllers?.index(of: viewController),
        index < tabBarTypes.count {
        let type = tabBarTypes[index]
        switch type {
        case .menu:
            // perform your menu presenting here
            return false
        case .controller:
            // do nothing, just return true, tab bar will do all work for you
            return true
        }
    }
    return true
}

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

Ответ 2

Его не очень хороший пользовательский интерфейс, но если хочешь.

Сначала вам необходимо реализовать метод делегирования UITabbarControllerDelegate, как показано ниже

func tabBarController(_ tabBarController: UITabBarController, shouldSelect 
 viewController: UIViewController) -> Bool {

    if viewController.classForCoder == moreViewController.self
    {   
        let popvc = MoreSubMenuViews(nibName: "MoreSubMenuViews", bundle: Bundle.main)
        self.addChildViewController(popvc)

        let tabbarHeight = tabBar.frame.height
        let estimatedWidth:CGFloat = 200.0
        let estimatedHeight:CGFloat = 300.0
        popvc.view.frame = CGRect(x:self.view.frame.width - estimatedWidth, y: self.view.frame.height - estimatedHeight - tabbarHeight, width: estimatedWidth, height: estimatedHeight)

        self.view.addSubview(popvc.view)

        popvc.didMove(toParentViewController: self)

        print("sorry stop here")
        return true // if you want not to select return false here

    }else{

        //remove popup logic here if opened
        return true
    }
} 

Здесь moreViewController - последний контроллер табуляции, а MoreSubMenuViews - файл nib/xib, который содержит кнопки, показанные на вашем изображении.

Ответ 3

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

Ответ 4

Это злоупотребление макетами пользовательского интерфейса в Apples HIG. В частности:

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

Этот элемент управления должен использоваться для выравнивания иерархии приложений. Кажется, что в этом случае вы смешиваете функциональность кнопки. Иногда он выбирает отдельный контроллер вида, иногда он отображает список действий. Это запутанная ситуация для пользователей, и ее следует избегать.

Способ, которым вы могли бы достичь этого и по-прежнему придерживаться HIG, - это использовать навигационные панели или панели инструментов. Вставьте этот элемент управления в кнопку панели инструментов. Самый простой случай - вызвать UIActionController с .actionSheet стилем .actionSheet.

Ответ 5

В соответствии с моим пониманием, что вы хотите, выберете вкладку 1, и пользователь перейдет на вкладку 5, тогда фон будет табуляцией 1 и наоборот для вкладок 2,3 и 4, и там должны появиться кнопки, как показано на вашем изображении, пожалуйста, поправьте меня, если я ошибаюсь.

Для этого вам нужно захватить изображение, пока пользователь перемещается по вкладкам.

Ниже приведен код в AppDelegate,

var currentImage: UIImage!//It will be public variable

Методы делегата Tabbar,

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    if tabBarController.selectedIndex == 4 {
        let moreVC = tabBarController.selectedViewController as! MoreVC
        moreVC.currentImage = currentImage
    }
}

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    if tabBarController.selectedIndex != 4 {
        let navController = tabBarController.selectedViewController as! UINavigationController
        let viewController = navController.viewControllers.last
        currentImage = Common.imageWithView(inView: (viewController?.navigationController?.view)!) //UIImage(view: (viewController?.navigationController?.view)!)
    }

    return true
}

Здесь я взял static 4 в качестве последнего индекса вкладки, а MoreVC будет ассоциированным ViewController индекса вкладки 4.

Общий класс для получения изображения из представления,

class Common {
    static func imageWithView(inView: UIView) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(inView.bounds.size, inView.isOpaque, 0.0)
        defer { UIGraphicsEndImageContext() }
        if let context = UIGraphicsGetCurrentContext() {
            inView.layer.render(in: context)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            return image
        }
        return nil
    }
}

Пожалуйста, найдите MoreVC,

@IBOutlet weak var imageView: UIImageView!

var currentImage: UIImage! {
    didSet {
        imageView.image = currentImage
    }
}

Ниже вы найдете изображение для раскадровки MoreVC. Посмотрите, что он не содержит NavigationController, как и все другие ViewControllers.

enter image description here

Дайте мне знать в случае любых запросов.

Ответ 6

1) Создайте "Tab5ViewController" и используйте это:

static func takeScreenshot(bottomPadding padding: CGFloat = 0) -> UIImage? {
        let layer = UIApplication.shared.keyWindow!.layer
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(CGSize(width: layer.frame.size.width, height: layer.frame.size.height - padding), false, scale)

        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        layer.render(in: context)
        let screenshot = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return screenshot
    }

Используйте скриншот в качестве фонового изображения для вашего "Tab5ViewController"

2) В вашем "Tab5ViewController" вы можете иметь компонент стека (дополнительные вкладки), а затем просто добавлять/удалять контроллеры дочерних представлений на основе выбора

3) исправить краевые случаи (например, выделение выделения вкладки и т.д.)