Меню из панели вкладок в раскадровке
На данный момент у меня есть стандартная панель вкладок, когда нажатие переходит к соответствующему 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) исправить краевые случаи (например, выделение выделения вкладки и т.д.)