El *_*oso 128 iphone objective-c uinavigationbar ios ios7
在新的iOS7 Facebook iPhone应用程序中,当用户向上滚动时,navigationBar逐渐隐藏自己到完全消失的程度.然后,当用户向下滚动时,navigationBar逐渐显示自己.
你会如何自己实现这种行为?我知道以下解决方案,但它立即消失,并没有与用户的滚动手势的速度挂钩.
[navigationController setNavigationBarHidden: YES animated:YES];
Run Code Online (Sandbox Code Playgroud)
我希望这不是重复,因为我不确定如何最好地描述"扩展/收缩"行为.
Way*_*ett 162
@peerless给出的解决方案是一个很好的开始,但它只会在拖动开始时启动动画,而不考虑滚动的速度.这会导致比Facebook应用程序更糟糕的体验.为了匹配Facebook的行为,我们需要:
首先,您需要以下属性:
@property (nonatomic) CGFloat previousScrollViewYOffset;
Run Code Online (Sandbox Code Playgroud)
以下是UIScrollViewDelegate方法:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect frame = self.navigationController.navigationBar.frame;
CGFloat size = frame.size.height - 21;
CGFloat framePercentageHidden = ((20 - frame.origin.y) / (frame.size.height - 1));
CGFloat scrollOffset = scrollView.contentOffset.y;
CGFloat scrollDiff = scrollOffset - self.previousScrollViewYOffset;
CGFloat scrollHeight = scrollView.frame.size.height;
CGFloat scrollContentSizeHeight = scrollView.contentSize.height + scrollView.contentInset.bottom;
if (scrollOffset <= -scrollView.contentInset.top) {
frame.origin.y = 20;
} else if ((scrollOffset + scrollHeight) >= scrollContentSizeHeight) {
frame.origin.y = -size;
} else {
frame.origin.y = MIN(20, MAX(-size, frame.origin.y - scrollDiff));
}
[self.navigationController.navigationBar setFrame:frame];
[self updateBarButtonItems:(1 - framePercentageHidden)];
self.previousScrollViewYOffset = scrollOffset;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self stoppedScrolling];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
willDecelerate:(BOOL)decelerate
{
if (!decelerate) {
[self stoppedScrolling];
}
}
Run Code Online (Sandbox Code Playgroud)
您还需要这些辅助方法:
- (void)stoppedScrolling
{
CGRect frame = self.navigationController.navigationBar.frame;
if (frame.origin.y < 20) {
[self animateNavBarTo:-(frame.size.height - 21)];
}
}
- (void)updateBarButtonItems:(CGFloat)alpha
{
[self.navigationItem.leftBarButtonItems enumerateObjectsUsingBlock:^(UIBarButtonItem* item, NSUInteger i, BOOL *stop) {
item.customView.alpha = alpha;
}];
[self.navigationItem.rightBarButtonItems enumerateObjectsUsingBlock:^(UIBarButtonItem* item, NSUInteger i, BOOL *stop) {
item.customView.alpha = alpha;
}];
self.navigationItem.titleView.alpha = alpha;
self.navigationController.navigationBar.tintColor = [self.navigationController.navigationBar.tintColor colorWithAlphaComponent:alpha];
}
- (void)animateNavBarTo:(CGFloat)y
{
[UIView animateWithDuration:0.2 animations:^{
CGRect frame = self.navigationController.navigationBar.frame;
CGFloat alpha = (frame.origin.y >= y ? 0 : 1);
frame.origin.y = y;
[self.navigationController.navigationBar setFrame:frame];
[self updateBarButtonItems:alpha];
}];
}
Run Code Online (Sandbox Code Playgroud)
对于略有不同的行为,请使用以下内容替换滚动(else块中scrollViewDidScroll)时重新定位条形的线:
frame.origin.y = MIN(20,
MAX(-size, frame.origin.y -
(frame.size.height * (scrollDiff / scrollHeight))));
Run Code Online (Sandbox Code Playgroud)
这会根据最后一个滚动百分比而不是绝对量来定位条形,这会导致较慢的淡入淡出.原来的行为更像Facebook,但我也喜欢这个.
注意:此解决方案仅适用于iOS 7+.如果您支持旧版iOS,请务必添加必要的检查.
Ped*_*mão 52
编辑:仅适用于iOS 8及更高版本.
你可以尝试使用
self.navigationController.hidesBarsOnSwipe = YES;
Run Code Online (Sandbox Code Playgroud)
适合我.
如果您使用swift进行编码,则必须使用这种方式(来自/sf/answers/1936389171/)
navigationController?.hidesBarsOnSwipe = true
Run Code Online (Sandbox Code Playgroud)
Maz*_*yod 43
这是另外一个实现:TLYShyNavBar v1.0.0发布了!
我决定在尝试提供的解决方案之后自己制作,对我而言,他们要么表现不佳,要么具有较高的进入障碍和锅炉板代码,要么缺少导航栏下方的扩展视图.要使用此组件,您所要做的就是:
self.shyNavBarManager.scrollView = self.scrollView;
Run Code Online (Sandbox Code Playgroud)
哦,它在我们自己的应用程序中进行了战斗测试.

小智 33
你可以看看我的GTScrollNavigationBar.我已经将UINavigationBar子类化,使其基于UIScrollView的滚动进行滚动.
注意:如果您有一个OPAQUE导航栏,则滚动视图必须EXPAND,因为导航栏会获得HIDDEN.这正是GTScrollNavigationBar所做的.(就像在iOS上的Safari一样.)
Mic*_*son 25
iOS8包含可以免费隐藏导航栏的属性.有一个WWDC视频演示它,搜索"iOS 8中的View Controller Advancements".
示例:
class QuotesTableViewController: UITableViewController {
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
navigationController?.hidesBarsOnSwipe = true
}
Run Code Online (Sandbox Code Playgroud)
}
其他性能:
class UINavigationController : UIViewController {
//... truncated
/// When the keyboard appears, the navigation controller's navigationBar toolbar will be hidden. The bars will remain hidden when the keyboard dismisses, but a tap in the content area will show them.
@availability(iOS, introduced=8.0)
var hidesBarsWhenKeyboardAppears: Bool
/// When the user swipes, the navigation controller's navigationBar & toolbar will be hidden (on a swipe up) or shown (on a swipe down). The toolbar only participates if it has items.
@availability(iOS, introduced=8.0)
var hidesBarsOnSwipe: Bool
/// The gesture recognizer that triggers if the bars will hide or show due to a swipe. Do not change the delegate or attempt to replace this gesture by overriding this method.
@availability(iOS, introduced=8.0)
var barHideOnSwipeGestureRecognizer: UIPanGestureRecognizer { get }
/// When the UINavigationController's vertical size class is compact, hide the UINavigationBar and UIToolbar. Unhandled taps in the regions that would normally be occupied by these bars will reveal the bars.
@availability(iOS, introduced=8.0)
var hidesBarsWhenVerticallyCompact: Bool
/// When the user taps, the navigation controller's navigationBar & toolbar will be hidden or shown, depending on the hidden state of the navigationBar. The toolbar will only be shown if it has items to display.
@availability(iOS, introduced=8.0)
var hidesBarsOnTap: Bool
/// The gesture recognizer used to recognize if the bars will hide or show due to a tap in content. Do not change the delegate or attempt to replace this gesture by overriding this method.
@availability(iOS, introduced=8.0)
unowned(unsafe) var barHideOnTapGestureRecognizer: UITapGestureRecognizer { get }
}
Run Code Online (Sandbox Code Playgroud)
通过http://natashatherobot.com/navigation-bar-interactions-ios8/找到
pee*_*ess 12
我有一些快速而肮脏的解决方案.没有进行任何深入测试,但这里的想法是:
该属性将保留导航栏中的所有项目以用于我的UITableViewController类
@property (strong, nonatomic) NSArray *navBarItems;
Run Code Online (Sandbox Code Playgroud)
在同一个UITableViewController类中,我有:
-(void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{
if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0f){
return;
}
CGRect frame = self.navigationController.navigationBar.frame;
frame.origin.y = 20;
if(self.navBarItems.count > 0){
[self.navigationController.navigationBar setItems:self.navBarItems];
}
[self.navigationController.navigationBar setFrame:frame];
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0f){
return;
}
CGRect frame = self.navigationController.navigationBar.frame;
CGFloat size = frame.size.height - 21;
if([scrollView.panGestureRecognizer translationInView:self.view].y < 0)
{
frame.origin.y = -size;
if(self.navigationController.navigationBar.items.count > 0){
self.navBarItems = [self.navigationController.navigationBar.items copy];
[self.navigationController.navigationBar setItems:nil];
}
}
else if([scrollView.panGestureRecognizer translationInView:self.view].y > 0)
{
frame.origin.y = 20;
if(self.navBarItems.count > 0){
[self.navigationController.navigationBar setItems:self.navBarItems];
}
}
[UIView beginAnimations:@"toggleNavBar" context:nil];
[UIView setAnimationDuration:0.2];
[self.navigationController.navigationBar setFrame:frame];
[UIView commitAnimations];
}
Run Code Online (Sandbox Code Playgroud)
这只适用于ios> = 7,我知道这很丑,但实现这一目标很快.欢迎任何意见/建议:)
Zho*_*wen 12
这适用于iOS 8及更高版本,并确保状态栏仍保留其背景
self.navigationController.hidesBarsOnSwipe = YES;
CGRect statuBarFrame = [UIApplication sharedApplication].statusBarFrame;
UIView *statusbarBg = [[UIView alloc] initWithFrame:statuBarFrame];
statusbarBg.backgroundColor = [UIColor blackColor];
[self.navigationController.view addSubview:statusbarBg];
Run Code Online (Sandbox Code Playgroud)
如果要在点击状态栏时显示导航栏,可以执行以下操作:
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView {
self.navigationController.navigationBarHidden = NO;
}
Run Code Online (Sandbox Code Playgroud)
Val*_*gin 10
这是我的实现:SherginScrollableNavigationBar.
在我的方法中,我KVO用于观察UIScrollView状态,因此没有必要使用委托(并且您可以将此委托用于您需要的任何其他内容).
请尝试我的解决方案,让我知道为什么这不如以前的答案好.
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
if (fabs(velocity.y) > 1)
[self hideTopBar:(velocity.y > 0)];
}
- (void)hideTopBar:(BOOL)hide
{
[self.navigationController setNavigationBarHidden:hide animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:UIStatusBarAnimationSlide];
}
Run Code Online (Sandbox Code Playgroud)
小智 6
我完成此任务的一种方法如下.
注册您的视图控制器UIScrollViewDelegate就是您UITableView的例子.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
Run Code Online (Sandbox Code Playgroud)
在de UIScrollViewDelegate方法中,您可以获得新的contentOffset并UINavigationBar相应地向上或向下翻译.
设置子视图的alpha也可以根据您可以设置和计算的某些阈值和因子来完成.
希望能帮助到你!
| 归档时间: |
|
| 查看次数: |
92397 次 |
| 最近记录: |