滚动UIWebView时隐藏和显示导航栏

4

我希望你能帮助我,我正在尝试构建一个应用程序,其中包含一个带有uiwebview和一个带有2个按钮的navbarviewcontroller。我想做的是,当用户滚动uiwebview时,导航栏会自动隐藏,就像向上滑动一样。但它没有按照我想要的方式工作。让我在这里发布代码。 在viewdidload中,我放置了以下内容。

[webPage.scrollView setDelegate:self];

然后我有这个方法

- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
    if(scrollView.contentOffset.y == 0) {
        //show
        NSLog(@"Show");
        [self.navigationController setNavigationBarHidden:NO animated:YES];
    } else {
        NSLog(@"Hide");
        [self.navigationController setNavigationBarHidden:YES animated:YES];
        //hide
    }
}

我可以正确地使用NSLog,但是navbar仍然保持不变。:(


请记住,didScroll 函数将在每个(几乎)像素变化时被调用。隐藏和显示的条件需要包含不等式,如 offset < someThreshold。 - danh
那你有什么建议呢?抱歉,我是新手。 :) - user2966615
3个回答

12

只需将此代码添加到 ViewController 实现文件 (.m) 中:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.webView.scrollView.delegate = self;
}  

#pragma mark - UIScrollViewDelegate Methods

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    self.lastOffsetY = scrollView.contentOffset.y;
}

- (void) scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
    bool hide = (scrollView.contentOffset.y > self.lastOffsetY);
    [[self navigationController] setNavigationBarHidden:hide animated:YES];

}

并且不要忘记在头文件(.h)中添加UIScrollViewDelegate协议:

@interface MyViewController : UIViewController <UIScrollViewDelegate>
    ...
@end

谢谢!请不要忘记在 @interface 上添加 lastOffsetY 属性:@property (nonatomic) CGFloat lastOffsetY; ;) - ffabri

4
您可以尝试以下步骤: 1. 声明导航栏,使用一个常量表示导航栏的高度,并声明两个 BOOL 变量:
UINavigationBar *navBar;

static const CGFloat kNavBarHeight = 60.0f;

BOOL webViewScrollIsDragging;
BOOL webViewScrollIsDecelerating;

2. 在viewDidLoad中写入以下内容:

 [webView.scrollView setContentInset:UIEdgeInsetsMake(kNavBarHeight, 0, 0, 0)];
 [webView.scrollView setScrollIndicatorInsets:UIEdgeInsetsMake(kNavBarHeight, 0, 0, 0)];
 [webView.scrollView setContentOffset:CGPointMake(0, -kNavBarHeight) animated:NO];
 webView.scrollView.delegate = self;

然后,初始化并将您的UINavigationBar作为self.view的子视图添加到原点(还要确保您的UIWebView具有相同的原点,即(0,0))。

3. 实现UIScrollViewDelegate方法(不要忘记添加UIScrollViewDelegate协议):

#pragma mark - UIScrollViewDelegate Methods
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (scrollView == webview.scrollView)
    {
        if (scrollView.contentOffset.y == 1 && !webViewScrollIsDragging && !webViewScrollIsDecelerating)
        {
            [UIView animateWithDuration:0.3
                                  delay:0.0
                                options: UIViewAnimationCurveEaseOut
                             animations:^(void) {
                                 CGRect navBarFrame = CGRectMake(0,-scrollView.contentOffset.y-kNavBarHeight, self.view.bounds.size.width, kNavBarHeight);
                                 navBar.frame = navBarFrame;
                             }
                             completion:nil];
        }
        else
        {
            CGRect navBarFrame = CGRectMake(0,-scrollView.contentOffset.y-kNavBarHeight, self.view.bounds.size.width, kNavBarHeight);
            navBar.frame = navBarFrame;
        }

        if (scrollView.contentOffset.y < -kNavBarHeight)
        {
            [webview.scrollView setScrollIndicatorInsets:UIEdgeInsetsMake(fabsf(scrollView.contentOffset.y), 0, 0, 0)];
        }
    }
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    if (scrollView == webview.scrollView)
    {
        webViewScrollIsDragging = YES;
    }
}

- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (scrollView == webview.scrollView)
    {
        webViewScrollIsDragging = NO;
    }
}

- (void) scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
    if (scrollView == webview.scrollView)
    {
        webViewScrollIsDecelerating = YES;
    }
}

- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if (scrollView == webview.scrollView)
    {
        webViewScrollIsDecelerating = NO;
    }
}

1
在iOS 8.0及更高版本中,只需使用一行代码:

self.navigationController.hidesBarsOnSwipe = YES;


/// 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.
//  @property (nonatomic, readwrite, assign) BOOL hidesBarsOnSwipe NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

当向下滑动时,将隐藏导航栏(并变为透明状态栏),当向上滑动时将显示导航栏,过程带有动画。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接