Как скрыть uitabbarcontroller
У меня проблема с UITabBarController
. В моем приложении я хочу скрыть его, но не используя hidesBottomBarWhenPushed
, потому что я хочу скрыть его не тогда, когда я его нажал. Например, я хочу скрыть его, когда я нажимаю кнопку "Скрыть" в своем приложении.
Я читал много статей в google, но я не могу узнать, как я могу это сделать.
Ответы
Ответ 1
Я вставляю это из своего рабочего кода... вы можете вызвать эти методы, чтобы скрыть и показать tabbarcontroller.... просто передать экземпляр tabbarcontroller для этих функций.
// Method call
[self hideTabBar:self.tabBarController];
// Method implementations
- (void)hideTabBar:(UITabBarController *) tabbarcontroller
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}
[UIView commitAnimations];
}
- (void)showTabBar:(UITabBarController *) tabbarcontroller
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
NSLog(@"%@", view);
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 431, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 431)];
}
}
[UIView commitAnimations];
}
Ответ 2
Измененный ответ Setomidor для работы как с ландшафтом, так и с портретом и iPad (значения 320 и 480 работают только на iPhone).
- (void) hideTabBar:(UITabBarController *) tabbarcontroller
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
float fHeight = screenRect.size.height;
if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) )
{
fHeight = screenRect.size.width;
}
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
view.backgroundColor = [UIColor blackColor];
}
}
[UIView commitAnimations];
}
- (void) showTabBar:(UITabBarController *) tabbarcontroller
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
float fHeight = screenRect.size.height - tabbarcontroller.tabBar.frame.size.height;
if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) )
{
fHeight = screenRect.size.width - tabbarcontroller.tabBar.frame.size.height;
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
}
}
[UIView commitAnimations];
}
Также был изменен код для обработки изменений, внесенных в iOS 6 с изменением ориентации UIDevice, и убедитесь, что он работает правильно, даже когда устройство лежит на спине.
Ответ 3
В вашем методе действий для кнопки:
[self.tabBarController.tabBar setHidden:YES];
Ответ 4
Решения Saurahb и karlbecker_com велики, хотя они могут вызвать очевидный эффект popping, когда представление содержит tableview, в то время как панель вкладок оживляет резервное копирование. Я внес некоторые изменения и объединил их в одну функцию (как категорию в UITabBarController). Он не полностью совершенный (отложенная коррекция анимации), но дает хорошие результаты с таблицами.
Если вам нравятся анимационные блоки и категории, попробуйте это. Ориентация и удобство в работе.
UITabBarController + ShowHideBar.m:
#import "UITabBarController+ShowHideBar.h"
@implementation UITabBarController (ShowHideBar)
- (void) setHidden:(BOOL)hidden{
CGRect screenRect = [[UIScreen mainScreen] bounds];
float fHeight = screenRect.size.height;
if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) ){
fHeight = screenRect.size.width;
}
if(!hidden) fHeight -= self.tabBar.frame.size.height;
[UIView animateWithDuration:0.25 animations:^{
for(UIView *view in self.view.subviews){
if([view isKindOfClass:[UITabBar class]]){
[view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)];
}else{
if(hidden) [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
}
}
}completion:^(BOOL finished){
if(!hidden){
[UIView animateWithDuration:0.25 animations:^{
for(UIView *view in self.view.subviews)
{
if(![view isKindOfClass:[UITabBar class]])
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
}
}];
}
}];
}
@end
UITabBarController + ShowHideBar.h:
#import <UIKit/UIKit.h>
@interface UITabBarController (ShowHideBar)
- (void) setHidden:(BOOL)hidden;
@end
Использование:
[self.tabBarController setHidden:YES];
[self.tabBarController setHidden:NO];
Ответ 5
Ответ Saurabh выше может быть расширен, чтобы также работать в альбомной ориентации:
+ (void) hideTabBar:(UITabBarController *) tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
//Support for landscape views
int orientation = [[UIDevice currentDevice] orientation];
int x_pos = 480;
if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
x_pos = 320;
}
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, x_pos, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, x_pos)];
}
}
[UIView commitAnimations];
}
`
Соответствующие номера x_pos для showTabBar() равны 431
и 271
.
Ответ 6
Это ответ karlbecker_com, портированный в MonoTouch (Xamarin.iOS).
Единственное различие заключается в том, что я реализовал методы класса, который наследуется от UITabBarController, поэтому ссылки на "tabbarcontroller
" были заменены на "this
".
public void HideTabBar()
{
var screenRect = UIScreen.MainScreen.Bounds;
float fHeight = screenRect.Height;
if(UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeLeft
|| UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeRight)
{
fHeight = screenRect.Width;
}
UIView.BeginAnimations(null);
UIView.SetAnimationDuration(0.4);
foreach(UIView view in this.View.Subviews)
{
if(view is UITabBar)
{
view.Frame = new RectangleF(view.Frame.X, fHeight, view.Frame.Width, view.Frame.Height);
}
else
{
view.Frame = new RectangleF(view.Frame.X, view.Frame.Y, view.Frame.Width, fHeight);
view.BackgroundColor = UIColor.Black;
}
}
UIView.CommitAnimations();
}
public void ShowTabBar()
{
var screenRect = UIScreen.MainScreen.Bounds;
float fHeight = screenRect.Height - 49f;
if(UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeLeft
|| UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeRight)
{
fHeight = screenRect.Width - 49f;
}
UIView.BeginAnimations(null);
UIView.SetAnimationDuration(0.4);
foreach(UIView view in this.View.Subviews)
{
if(view is UITabBar)
{
view.Frame = new RectangleF(view.Frame.X, fHeight, view.Frame.Width, view.Frame.Height);
}
else
{
view.Frame = new RectangleF(view.Frame.X, view.Frame.Y, view.Frame.Width, fHeight);
}
}
UIView.CommitAnimations();
}
Ответ 7
@karlbecker_com Answer работает идеально подходит как для iPhone 4, так и для iPhone 5. Если у кого-то возникают проблемы с черной полосой iOS7 внизу, установите tabBarController в полупрозрачный
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
// To Hide the black line in IOS7 only, this extra bit is required
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
[self.tabBarController.tabBar setTranslucent:YES];
}
Ответ 8
вы можете нажать контроллер модального просмотра
[self presentModalViewController:myFullscreenViewController animated:YES];
это создаст полностью новый полноэкранный вид над вашим текущим.
отклонить ist с помощью dismissModalViewController:animated:
Ответ 9
Решение ниже отлично работает для меня в точно таком же случае, когда мне нужно перейти в полноэкранный режим с анимацией TabBar.
В принципе, идея
-
сделать снимок UITabBar;
-
добавьте UIImage моментального снимка в UIImageView, который имеет тот же фрейм, что и UITabBar;
-
измените размер основного представления и поместите его на self.tabBarController.view;
-
установить UITabBar альфа 0.0,
-
разместите UIImageView с помощью UITabBar моментального снимка на self.tabBarController.view;
-
Как только это будет достигнуто, выполните любую анимацию
#import "QuartzCore/CALayer.h"
@implementation FTBFirstViewController {
BOOL hidden;
UIImageView *fakeTabBarImageView;
UIView *viewToResize;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//////////////////////////////
// Create your viewToResize
//////////////////////////////
[self.view addSubview:viewToResize];
hidden = NO;
}
- (void)hideTabBar:(id)sender {
if (!hidden) {
//
// to create the fake UITabBar
fakeTabBarImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
UIImage *fakeTabBarImage = [self imageScreenshotFromView:self.tabBarController.tabBar];
fakeTabBarImageView.image = fakeTabBarImage;
fakeTabBarImageView.frame = self.tabBarController.tabBar.frame;
//
// to resize underlying UIView
viewToResize.frame = (CGRect){viewToResize.frame.origin.x, viewToResize.frame.origin.y + 20.f, viewToResize.frame.size.width, viewToResize.frame.size.height + fakeTabBarImageView.frame.size.height};
//
// to hide real UITabBar
self.tabBarController.tabBar.alpha = 0.0;
//
// to add views in exactly this order
[self.tabBarController.view addSubview:viewToResize];
[self.tabBarController.view addSubview:fakeTabBarImageView];
//
// do any sort of animation
[UIView animateWithDuration:0.8 animations:^{
fakeTabBarImageView.frame = (CGRect){fakeTabBarImageView.frame.origin.x, fakeTabBarImageView.frame.origin.y + fakeTabBarImageView.frame.size.height, fakeTabBarImageView.frame.size};
}];
hidden = YES;
} else {
[UIView animateWithDuration:0.8 animations:^{
fakeTabBarImageView.frame = (CGRect){fakeTabBarImageView.frame.origin.x, fakeTabBarImageView.frame.origin.y - fakeTabBarImageView.frame.size.height, fakeTabBarImageView.frame.size};
} completion:^(BOOL complete){
self.tabBarController.tabBar.alpha = 1.0;
[fakeTabBarImageView removeFromSuperview];
fakeTabBarImageView = nil;
viewToResize.frame = self.view.frame;
[self.view addSubview:viewToResize];
[fakeTabBarImageView removeFromSuperview];
}];
hidden = NO;
}
}
- (UIImage *)imageScreenshotFromView:(UIView *)aView {
UIImage *viewImage;
UIGraphicsBeginImageContextWithOptions(aView.bounds.size, aView.opaque, [[UIScreen mainScreen] scale]);
[aView.layer renderInContext:UIGraphicsGetCurrentContext()];
viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}
Ответ 10
Я пробовал почти все эти ответы, но никто из них не работал у меня. Мое приложение имеет UITabBarController в качестве корневого представления, и на каждой вкладке есть UINavigationController. Один из UINavigationControllers имеет UICollectionViewController как контроллер верхнего уровня. Когда пользователь выбирает элемент в UICollectionView, я хотел, чтобы контроллер представления подробностей попал в стек навигации. Тогда у моего детального вида была панель инструментов внизу. Я не хотел, чтобы панель инструментов отображалась поверх панели вкладок, так как это выглядит тупо, и переключение контекстов вкладок не понадобится из этого представления. Я, вероятно, мог бы легко решить это, вручную разместив UIToolbars и UITabBars, а не используя UITabBarController и встроенный UIToolbar, но это выглядело слишком много рефакторинга и немного неэлегантным.
В итоге мое решение было довольно простым: расширьте границы UITabBarController в нижней части экрана. Я добавил это в контроллер подробного представления:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Extend the UITabBarController to shift the tab bar off screen
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGRect tabBarControllerFrame = self.tabBarController.view.frame;
if (animated) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
tabBarControllerFrame.size.height = screenRect.size.height +
self.tabBarController.tabBar.frame.size.height;
[self.tabBarController.view setFrame:tabBarControllerFrame];
[UIView commitAnimations];
}
else {
tabBarControllerFrame.size.height = screenRect.size.height +
self.tabBarController.tabBar.frame.size.height;
[self.tabBarController.view setFrame:tabBarControllerFrame];
}
// Now show the toolbar
[self.navigationController setToolbarHidden:NO animated:animated];
}
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
// Ensure the UITabBarController remains extended when subviews are laid out
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGRect tabBarControllerFrame = self.tabBarController.view.frame;
tabBarControllerFrame.size.height = screenRect.size.height +
self.tabBarController.tabBar.frame.size.height;
[self.tabBarController.view setFrame:tabBarControllerFrame];
}
Затем, чтобы просмотреть панель вкладок, когда пользователь вернется в верхнюю часть моего UINavigationController, я добавил это в свой контроллер верхнего уровня:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Hide toolbar
[self.navigationController setToolbarHidden:YES animated:animated];
// Tab bar back on to screen
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGRect tabBarControllerFrame = self.tabBarController.view.frame;
if (tabBarControllerFrame.size.height != screenRect.size.height) {
if (animated) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
tabBarControllerFrame.size.height = screenRect.size.height;
[self.tabBarController.view setFrame:tabBarControllerFrame];
[UIView commitAnimations];
}
else {
tabBarControllerFrame.size.height = screenRect.size.height;
[self.tabBarController.view setFrame:tabBarControllerFrame];
}
}
}
Ответ 11
в iOS8 достаточно просто установить свойство hidden
для tabBar
Как и в Swift, вы можете
rootTabVC = UITabBarController()
rootTabVC?.tabBar.hidden = true
Я делаю это в своем didFinishLaunchingWithOptions
в appdelegate
, и он отлично работает, я думаю, что если я правильно помню в старых версиях iOS, вам также нужно было установить frame
tabBar
на что-то вне в противном случае tabBar
не будет отображаться, но он все равно будет занимать пространство.
Ответ 12
Так как IOS 7.1, "Быстрое" решение:
self.tabBarController?.tabBar.hidden = true // hide tabbar
self.tabBarController?.tabBar.hidden = false // show tabbar
Надеюсь, это поможет!
Ответ 13
Быстрая и измененная версия кода @Saurabh
Метод
func setTabBarHidden (bool:Bool){
for view in tabBarController!.view.subviews {
if (view.isKindOfClass(UITabBar)){
let tabBar = view as! UITabBar
UIView.animateWithDuration(0.3, animations: { () -> Void in
var offset = CGFloat(50)
if (bool == false){
offset = -50;
}
tabBar.frame = CGRect(origin: CGPointMake(tabBar.frame.origin.x, tabBar.frame.origin.y + offset), size: tabBar.frame.size)
})
}
}
}
Чтобы показать
override func viewDidLoad() {
setTabBarHidden(true)
}
Чтобы скрыть
override func viewWillDisappear(animated: Bool) {
setTabBarHidden(false)
}
Ответ 14
Здесь находится уменьшенный быстрый порт версии @Thomas Verbeek для этих VC без таблиц (проверен в iOS 8.4):
extension UITabBarController {
/**
Shows or hides the tabbar
:param: hidden whether to show or hide the tabbar
:param: animationDuration the animation duration
*/
func setHidden(hidden:Bool, animationDuration:NSTimeInterval = 0.25) {
let screenRect = UIScreen.mainScreen().bounds
var fHeight = screenRect.size.height
if !hidden {
fHeight -= self.tabBar.frame.size.height
}
UIView.animateWithDuration(animationDuration, animations: {
for view in self.view.subviews as! [UIView] {
if view is UITabBar {
view.frame = CGRectMake(
view.frame.origin.x,
fHeight,
view.frame.size.width,
view.frame.size.height)
}
}
})
}
}
А вот более прямой порт (не тестировался):
extension UITabBarController {
/**
Shows or hides the tabbar
:param: hidden whether to show or hide the tabbar
:param: animationDuration the animation duration
*/
func setHidden(hidden:Bool, animationDuration:NSTimeInterval = 0.25) {
let screenRect = UIScreen.mainScreen().bounds
var fHeight = screenRect.size.height
if UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) {
fHeight = screenRect.size.width
}
if !hidden {
fHeight -= self.tabBar.frame.size.height
}
UIView.animateWithDuration(animationDuration, animations: {
for view in self.view.subviews as! [UIView] {
if view is UITabBar {
view.frame = CGRectMake(
view.frame.origin.x,
fHeight,
view.frame.size.width,
view.frame.size.height)
}
else if hidden {
view.frame = CGRectMake(
view.frame.origin.x,
view.frame.origin.y,
view.frame.size.width,
fHeight)
}
}
}, completion: { finished in
if !hidden {
UIView.animateWithDuration(animationDuration, animations: {
for view in self.view.subviews as! [UIView] {
if !(view is UITabBar) {
view.frame = CGRectMake(
view.frame.origin.x,
view.frame.origin.y,
view.frame.size.width,
fHeight)
}
}
})
}
})
}
}
Ответ 15
Скрытие панели вкладок не является адекватным решением, оно не будет регулировать высоту просмотра регуляторов текущего вида.
Вместо этого вы можете просто преобразовать панель вкладок самостоятельно, либо с помощью высоты (чтобы скрыть), либо преобразования идентификатора, чтобы сбрасывать на видимый.
extension UITabBarController {
func setBarHiddenAnimated(_ hidden:Bool) {
UIView.animate(withDuration: 0.3, animations: {
if hidden {
self.tabBar.transform = CGAffineTransform(translationX: 0, y: self.tabBar.frame.size.height)
} else {
self.tabBar.transform = CGAffineTransform.identity
}
})
}
}
Обратите внимание, что вам может потребоваться настроить контроллер вида "extends under bottom bars" и "extends under opque bars", чтобы удалить черный фон во время анимации.
Ответ 16
Быстрая версия с анимацией, вам нужно установить свойство isHideTabBar
самостоятельно.
self.isHideTabBar = !self.isHideTabBar
UIView.animate(withDuration: 0.5, animations: {
self.tabBarController?.tabBar.frame = (self.tabBarController?.tabBar.frame.offsetBy(dx: 0, dy: self.isHideTabBar ? 100 : -100))!
})