Как скрыть панель вкладок с анимацией в iOS?
Итак, у меня есть кнопка, подключенная к IBAction. Когда я нажимаю кнопку, я хочу скрыть панель вкладок в моем приложении iOS с помощью анимации. Этот [self setTabBarHidden:hidden animated:NO];
или этот [self.tabBarController setTabBarHidden:hidden animated:YES];
не работает. Это мой код без анимации:
- (IBAction)picture1:(id)sender {
[self.tabBarController.tabBar setHidden:YES];
}
Любая помощь будет принята с благодарностью: D
Ответы
Ответ 1
Я пытаюсь сохранить анимацию просмотра доступной для меня, используя следующую формулу:
// pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion
- (void)setTabBarVisible:(BOOL)visible animated:(BOOL)animated completion:(void (^)(BOOL))completion {
// bail if the current state matches the desired state
if ([self tabBarIsVisible] == visible) return (completion)? completion(YES) : nil;
// get a frame calculation ready
CGRect frame = self.tabBarController.tabBar.frame;
CGFloat height = frame.size.height;
CGFloat offsetY = (visible)? -height : height;
// zero duration means no animation
CGFloat duration = (animated)? 0.3 : 0.0;
[UIView animateWithDuration:duration animations:^{
self.tabBarController.tabBar.frame = CGRectOffset(frame, 0, offsetY);
} completion:completion];
}
//Getter to know the current state
- (BOOL)tabBarIsVisible {
return self.tabBarController.tabBar.frame.origin.y < CGRectGetMaxY(self.view.frame);
}
//An illustration of a call to toggle current state
- (IBAction)pressedButton:(id)sender {
[self setTabBarVisible:![self tabBarIsVisible] animated:YES completion:^(BOOL finished) {
NSLog(@"finished");
}];
}
Ответ 2
При работе с раскадрой его легко настроить контроллер просмотра, чтобы скрыть табуляцию при нажатии, на целевом контроллере просмотра просто установите этот флажок:
![enter image description here]()
Ответ 3
В соответствии с документами Apple, hidesBottomBarWhenPushed свойство UIViewController - логическое значение, указывающее, скрыта ли панель инструментов в нижней части экрана, когда контроллер представления нажат на контроллер навигации.
Значение этого свойства на верхнем контроллере представления определяет, является ли панель инструментов видимой.
Рекомендуемый подход к скрытию панели вкладок будет следующим образом
ViewController *viewController = [[ViewController alloc] init];
viewController.hidesBottomBarWhenPushed = YES; // This property needs to be set before pushing viewController to the navigationController stack.
[self.navigationController pushViewController:viewController animated:YES];
Однако обратите внимание, что этот подход будет применяться только к соответствующему диспетчеру viewController и не будет распространяться на другие контроллеры представлений, если вы не начнете устанавливать одно и то же свойство hidesBottomBarWhenPushed в других viewControllers, прежде чем нажимать его на стек контроллера навигации.
Ответ 4
Быстрая версия:
@IBAction func tap(sender: AnyObject) {
setTabBarVisible(!tabBarIsVisible(), animated: true, completion: {_ in })
}
// pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion
func setTabBarVisible(visible: Bool, animated: Bool, completion:(Bool)->Void) {
// bail if the current state matches the desired state
if (tabBarIsVisible() == visible) {
return completion(true)
}
// get a frame calculation ready
let height = tabBarController!.tabBar.frame.size.height
let offsetY = (visible ? -height : height)
// zero duration means no animation
let duration = (animated ? 0.3 : 0.0)
UIView.animateWithDuration(duration, animations: {
let frame = self.tabBarController!.tabBar.frame
self.tabBarController!.tabBar.frame = CGRectOffset(frame, 0, offsetY);
}, completion:completion)
}
func tabBarIsVisible() -> Bool {
return tabBarController!.tabBar.frame.origin.y < CGRectGetMaxY(view.frame)
}
Ответ 5
версия Swift 3.0 с использованием расширения:
extension UITabBarController {
private struct AssociatedKeys {
// Declare a global var to produce a unique address as the assoc object handle
static var orgFrameView: UInt8 = 0
static var movedFrameView: UInt8 = 1
}
var orgFrameView:CGRect? {
get { return objc_getAssociatedObject(self, &AssociatedKeys.orgFrameView) as? CGRect }
set { objc_setAssociatedObject(self, &AssociatedKeys.orgFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
}
var movedFrameView:CGRect? {
get { return objc_getAssociatedObject(self, &AssociatedKeys.movedFrameView) as? CGRect }
set { objc_setAssociatedObject(self, &AssociatedKeys.movedFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
}
override open func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if let movedFrameView = movedFrameView {
view.frame = movedFrameView
}
}
func setTabBarVisible(visible:Bool, animated:Bool) {
//since iOS11 we have to set the background colour to the bar color it seams the navbar seams to get smaller during animation; this visually hides the top empty space...
view.backgroundColor = self.tabBar.barTintColor
// bail if the current state matches the desired state
if (tabBarIsVisible() == visible) { return }
//we should show it
if visible {
tabBar.isHidden = false
UIView.animate(withDuration: animated ? 0.3 : 0.0) {
//restore form or frames
self.view.frame = self.orgFrameView!
//errase the stored locations so that...
self.orgFrameView = nil
self.movedFrameView = nil
//...the layoutIfNeeded() does not move them again!
self.view.layoutIfNeeded()
}
}
//we should hide it
else {
//safe org positions
orgFrameView = view.frame
// get a frame calculation ready
let offsetY = self.tabBar.frame.size.height
movedFrameView = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height + offsetY)
//animate
UIView.animate(withDuration: animated ? 0.3 : 0.0, animations: {
self.view.frame = self.movedFrameView!
self.view.layoutIfNeeded()
}) {
(_) in
self.tabBar.isHidden = true
}
}
}
func tabBarIsVisible() ->Bool {
return orgFrameView == nil
}
}
- Это основано на вкладе Шервина Заде после нескольких часов игры.
- Вместо того, чтобы перемещать саму вкладку, она перемещает рамку представления, это эффективно скользит по вкладке хорошо из нижней части экрана, но...
- ... имеет то преимущество, что содержимое, отображаемое внутри UITabbarcontroller, также принимает весь экран!
- обратите внимание, что он также использует функциональность AssociatedObject для прикрепленных данных к UIView без подкласса и, следовательно, возможно расширение (расширения не позволяют сохранять сохраненные свойства).
![введите описание изображения здесь]()
Ответ 6
Попробуйте установить рамку tabBar в анимации. См. этот учебник.
Просто имейте в виду, что это плохая практика, вы должны установить show/hide tabBar, когда UIViewController
нажмите, установив свойство hidesBottomBarWhenPushed
в YES
.
Ответ 7
попробовал в swift 3.0/iOS10/Xcode 8:
self.tabBarController?.tabBar.isHidden = true
Я устанавливаю его, когда отображается мой контроллер: (и Скрыть, когда он вернулся, после навигации)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.tabBar.isHidden = false
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.tabBarController?.tabBar.isHidden = true
}
BTW: лучше иметь флаг для сохранения, если он показан, или нет, поскольку другие вентиляционные отверстия могут в конечном итоге вызвать hide/show
Ответ 8
К сожалению, я не могу комментировать ответ HixField, потому что у меня недостаточно репутации, поэтому я должен оставить это как отдельный ответ.
В его ответе отсутствует вычисленное свойство для movedFrameView
, которое:
var movedFrameView:CGRect? {
get { return objc_getAssociatedObject(self, &AssociatedKeys.movedFrameView) as? CGRect }
set { objc_setAssociatedObject(self, &AssociatedKeys.movedFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
}
Ответ 9
Перепишите ответ Шервина Заде в Swift 4:
/* tab bar hide/show animation */
extension AlbumViewController {
// pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion
func setTabBarVisible(visible: Bool, animated: Bool, completion: ((Bool)->Void)? = nil ) {
// bail if the current state matches the desired state
if (tabBarIsVisible() == visible) {
if let completion = completion {
return completion(true)
}
else {
return
}
}
// get a frame calculation ready
let height = tabBarController!.tabBar.frame.size.height
let offsetY = (visible ? -height : height)
// zero duration means no animation
let duration = (animated ? kFullScreenAnimationTime : 0.0)
UIView.animate(withDuration: duration, animations: {
let frame = self.tabBarController!.tabBar.frame
self.tabBarController!.tabBar.frame = frame.offsetBy(dx: 0, dy: offsetY)
}, completion:completion)
}
func tabBarIsVisible() -> Bool {
return tabBarController!.tabBar.frame.origin.y < view.frame.maxY
}
}
Ответ 10
Это для меня:
[self.tabBar setHidden:YES];
где self - контроллер вида, tabBar - это идентификатор для tabBar.