3

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.

Rishil Patel
  • 1,977
  • 3
  • 14
  • 30
Mike Rundle
  • 486
  • 4
  • 9
  • Similar issues: http://stackoverflow.com/questions/21929220/show-hide-uitoolbar-match-finger-movement-precisely-as-in-for-example-ios7-s It is extremely subtle to do it EXACTLY like safari.... – Fattie Feb 28 '14 at 20:39

3 Answers3

4

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

Rishil Patel
  • 1,977
  • 3
  • 14
  • 30
gimenete
  • 2,649
  • 1
  • 20
  • 16
  • I want to do the same effect but with UIWebview? how can i do this? because it doesnt have a header view so that kind of hard. right now i just move the nav bar, and have the web view frame the same and i don't have the clips subviews on, so i can see still and it gets the effect, but it doesnt allow touches! so i cant scroll at the top and i some people might so that could be a issue for me. – Maximilian Litteral Oct 06 '12 at 20:24
1

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.

Brian Stormont
  • 1,179
  • 7
  • 15
0

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.

Thomas Tempelmann
  • 11,045
  • 8
  • 74
  • 149