Mike Rundle
Mike Rundle

Reputation: 486

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.

Upvotes: 3

Views: 2667

Answers (3)

gimenete
gimenete

Reputation: 2669

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

Upvotes: 4

Brian Stormont
Brian Stormont

Reputation: 1189

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.

Upvotes: 1

Thomas Tempelmann
Thomas Tempelmann

Reputation: 12075

Can't give you a straight answer, but have a look at iWebKit. Maybe that provides a solution. The demo, at least, contains a "full screen" item.

Upvotes: 0

Related Questions