我想知道如何实现在向下拖动时隐藏标签栏的动画,例如iOS 7上的Safari应用程序。任何来自您的信息都将受到赞赏。
类似的问题:Show/hide UIToolbar, "match finger movement", precisely as in for example iOS7 Safari。
答案 0 :(得分:18)
这样的事情应该有效。我不知道这是否与Safari应用程序具有完全相同的外观,但它很接近:
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (nonatomic) CGRect originalFrame;
@end
@implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, 1000);
self.originalFrame = self.tabBarController.tabBar.frame;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
UITabBar *tb = self.tabBarController.tabBar;
NSInteger yOffset = scrollView.contentOffset.y;
if (yOffset > 0) {
tb.frame = CGRectMake(tb.frame.origin.x, self.originalFrame.origin.y + yOffset, tb.frame.size.width, tb.frame.size.height);
}
if (yOffset < 1) tb.frame = self.originalFrame;
}
答案 1 :(得分:8)
当您在表格视图中有大量单元格时,接受的答案不起作用 - 如果您一直滚动到顶部,则仅显示标签栏。
我改进了这样:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, 1000);
self.originalFrame = self.tabBarController.tabBar.frame;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
UITabBar *tabBar = self.tabBarController.tabBar;
NSInteger yOffset = scrollView.contentOffset.y;
CGFloat yPanGesture = [scrollView.panGestureRecognizer translationInView:self.view].y;
CGFloat heightTabBar = tabBar.frame.size.height;
CGFloat tabBarOriginY = tabBar.frame.origin.y;
CGFloat frameHeight = self.view.frame.size.height;
if(yOffset>=heightTabBar)
yOffset = heightTabBar;
// GOING UP ------------------
if(yPanGesture >= 0 && yPanGesture < heightTabBar && tabBarOriginY > frameHeight-heightTabBar){
yOffset = heightTabBar - fabsf(yPanGesture);
}
else if(yPanGesture >= 0 && yPanGesture < heightTabBar && tabBarOriginY <= frameHeight-heightTabBar){
yOffset = 0;
}
// GOING DOWN ------------------
else if(yPanGesture < 0 && tabBarOriginY < frameHeight){
yOffset = fabsf(yPanGesture);
}else if(yPanGesture < 0 && tabBarOriginY >= frameHeight){
yOffset = heightTabBar;
}
else{
yOffset = 0;
}
if (yOffset > 0) {
tabBar.frame = CGRectMake(tabBar.frame.origin.x, self.originalFrame.origin.y + yOffset, tabBar.frame.size.width, tabBar.frame.size.height);
}
else if (yOffset <= 0){
tabBar.frame = self.originalFrame;
}
}
- (void)scrollViewWillEndDragging:(UIScrollView*)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
// Handle unfinished animations
UITabBar *tabBar = self.tabBarController.tabBar;
CGFloat yPanGesture = [scrollView.panGestureRecognizer translationInView:self.view].y;
CGFloat heightTabBar = tabBar.frame.size.height;
CGFloat tabBarOriginY = tabBar.frame.origin.y;
CGFloat frameHeight = self.view.frame.size.height;
if(yPanGesture > 0){
if(tabBarOriginY != frameHeight - heightTabBar) {
[UIView animateWithDuration:0.3 animations:^(void){
tabBar.frame = self.originalFrame;
}];
}
}else if(yPanGesture < 0){
if (tabBarOriginY != frameHeight) {
[UIView animateWithDuration:0.3 animations:^(void){
tabBar.frame = CGRectMake(tabBar.frame.origin.x, frameHeight, tabBar.frame.size.width, tabBar.frame.size.height);
}];
}
}
}
答案 2 :(得分:3)
老实说,我尝试了所有这些解决方案,但它们对我来说还不够强大。它们会在显示时隐藏标签栏,或者以奇怪的方式移动标签栏。
我最终花了一整天努力让他们上班。我终于放弃并使用了:https://github.com/tristanhimmelman/HidingNavigationBar。
这给了我隐藏导航栏和标签栏的功能(这是我首先想要的)。它运作得非常好,我在10分钟内完成设置。
希望这有助于其他人不要失去一天的编码:-0。
答案 3 :(得分:1)
您可以使用变量来保留lastContentOffset值。 标签栏origin.y的主要思想是CGRectGetMaxY(screenRect)和CGRectGetMaxY(screenRect) - CGRectGetHeight(tabBarRect)。
它在我的项目中运作良好。
@interface ViewController ()
@property (nonatomic, assign) CGFloat lastContentOffsetY;
@end
@implementation ViewController
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!self.tabBarController) {
return;
}
BOOL isStatusBarHidden = [UIApplication sharedApplication].isStatusBarHidden;
CGFloat kStatusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
if (scrollView.contentOffset.y > (scrollView.contentSize.height - scrollView.frame.size.height)
|| (scrollView.contentOffset.y < (isStatsuBarHidden ? 0 : -kStatusBarHeight))) {
// bottom & top bouncing - don't need to update
return;
}
CGFloat offset = scrollView.contentOffset.y - self.lastContentOffsetY;
CGRect tabBarRect = self.tabBarController.tabBar.frame;
CGRect screenRect = [UIScreen mainScreen].bounds;
if (CGRectGetMaxY(tabBarRect) == CGRectGetMaxY(screenRect) + CGRectGetHeight(tabBarRect)) {
//view could only scroll downward
if (offset < 0) {
tabBarRect.origin.y += offset;
}
} else if (CGRectGetMaxY(tabBarRect) == CGRectGetMaxY(screenRect)) {
//view could only scroll upward
if (offset > 0) {
tabBarRect.origin.y += offset;
}
} else {
//view could scroll upward & downward
tabBarRect.origin.y += offset;
}
//safty reset handling
if (CGRectGetMaxY(tabBarRect) > CGRectGetMaxY(screenRect) + CGRectGetHeight(tabBarRect)) {
tabBarRect.origin.y = CGRectGetMaxY(screenRect);
} else if (CGRectGetMaxY(tabBarRect) < CGRectGetMaxY(screenRect)) {
tabBarRect.origin.y = CGRectGetMaxY(screenRect) - CGRectGetHeight(tabBarRect); // over bouncing, set it back
}
self.tabBarController.tabBar.frame = tabBarRect;
self.lastContentOffsetY = scrollView.contentOffset.y;
}
答案 4 :(得分:0)
好吧,虽然其他人的所有答案既不起作用也不起作用,但@RobNorback的HidingNavigationBar效果非常好,实际上很容易设置。
然而,我在框架方面遇到了一些困难,花了2个小时修复它,所以我加了两分钱让某人不能进入相同的包装。
如果集合视图或表格视图中的项目或行数较少,则不会隐藏导航栏(或标签栏或工具栏),即使项目或行数足够大超越屏幕。您应该添加更多的项目或行,以使框架正确隐藏栏。
答案 5 :(得分:0)
static CGFloat navBarOriginY = 20.0;
为导航栏原点Y位置的基值创建常量
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.hidesBarsOnSwipe = true;
[self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipe:)];
}
添加自定义选择器以处理系统滑动手势,该手势将在导航栏隐藏和隐藏
之前触发- (void)swipe:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled || recognizer.state == UIGestureRecognizerStateFailed) {
如果手势状态结束/取消或失败,则需要完全更改tabBar的框架
CGRect finalFrame = self.tabBarController.tabBar.frame;
if (self.navigationController.navigationBar.frame.origin.y < 0) {
//Tab bar will be hidden
finalFrame.origin.y = self.maxTabBarY;
} else {
//Tab bar will be visible
finalFrame.origin.y = self.minTabBarY;
}
[self setFrameForTabBar:finalFrame animationDuration:0.3];
} else if (recognizer.state == UIGestureRecognizerStateChanged) {
如果状态==更改,则需要使用navBar平移你的tabBar,就像在safari app中一样。
CGRect frame = self.tabBarController.tabBar.frame;
CGFloat delta = navBarOriginY - self.navigationController.navigationBar.layer.presentationLayer.frame.origin.y;
frame.origin.y = self.minTabBarY + delta;
[self setFrameForTabBar:frame animationDuration:0.0];
} } }
- (void)setFrameForTabBar:(CGRect)frame animationDuration:(CGFloat)duration {
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
self.tabBarController.tabBar.frame = frame;
} completion:^(BOOL finished) {}];
});