Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scrollable UINavigationBar similar to Mobile Safari

My application uses a UINavigationController and the final view (detail view) lets you view an external website within the application using a UIWebView.

I'd like to free up some additional screen real estate when the user is viewing a webpage and wanted to emulate how Safari on iPhone works where their URL bar at the top scrolls up and off the screen when you're viewing content in the UIWebView that's below the fold.

Anyone have ideas on how to achieve this? If I set the navigationBarHidden property and roll my own custom bar at the top and set it and a UIWebView within a UIScrollView then there are scrolling issues in the UIWebView as it doesn't play nicely with other scrollable views.

like image 209
Mike Rundle Avatar asked Feb 02 '26 12:02

Mike Rundle


2 Answers

Based on @Brian suggestion I made this code:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat height = navigationBar.frame.size.height;
    CGFloat y = scrollView.bounds.origin.y;
    if (y <= 0) {
        CGRect frame = navigationBar.frame;
        frame.origin.y = 0;
        navigationBar.frame = frame;
    } else if (tableView.contentSize.height > tableView.frame.size.height) {
        CGFloat diff = height - y;
        CGRect frame = navigationBar.frame;
        frame.origin.y = -y;
        navigationBar.frame = frame;

        CGFloat origin = 0;
        CGFloat h = height; // height of the tableHeaderView
        if (diff > 0) {
            origin = diff;
            h = y;
        }
        frame = tableView.frame;
        frame.origin.y = origin;
        frame.size.height = tableView.superview.frame.size.height - origin;
        tableView.frame = frame;

        CGRect f = CGRectMake(0, 0, tableView.frame.size.width, h);
        UILabel* label = [[UILabel alloc] initWithFrame:f];
        tableView.tableHeaderView = label;
        [label release];
    }
}

My code has a UITableView but should work with any scrollable component. If you have other components than the navigationBar and the UIScrollView subclass, you should change the way the height of the scrollable component is calculated. Something like this:

frame.size.height = tableView.superview.frame.size.height - origin - otherComponentsHeight;

I needed to add a dumb tableHeaderView to have the desired behaviour. The problem was that when scrollViewDidScroll: is called the content has an offset, but the apparience in Mobile Safari is that the content is not scrolled until the navigationBar fully disappears. I tried first changing the contentOffset.y to 0, but obviously it didn't work since all the code relies on the scrolling mechanism. So I just added a tableHeaderView whose height is exactly the scrolled offset, so the header is never really seen, and the content appears to not scroll until the navigationBar fully disappears.

If you don't add the dumb tableHeaderView, then the scrollable component appears to scroll behind the navigationBar.

enter image description here

With the tableHeaderView, the scrollable component is actually scrolling (as seen in the scrollbar), but since there is a tableHeaderView whose height is exactly the same than the scrolled offset, the scrollable content appears to not be scrolling until the navigationBar fully disappears:

enter image description here

like image 171
gimenete Avatar answered Feb 04 '26 01:02

gimenete


Have a delegate for the scrolling events in the UIWebView and when you initially start scrolling the UIWebView, have the UIWebView increase in height and have it's Y position decrease at the same time while simultaneously shifting the nav bar up in the Y direction. Once the nav bar has been completely shifted out of view, stop increasing the size of the UIWebView and just allow normal scrolling to occur.

This will give the illusion of the nav bar being part of the UIWebView as it scrolls off the screen.

Also, you'll need to do the reverse when you are scrolling in the opposite direction and are reaching the top of the content of the UIWebView.

like image 41
Brian Stormont Avatar answered Feb 04 '26 00:02

Brian Stormont



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!