6

I have a UIWebView which I want to put under my translucent UINavigationBar. Normally when I put a UIScrollView under a translucent UINavigationBar, I set its contentOffset such that all content will be initially pushed after the bar so that it can be seen; thereafter, the user can scroll text and it will underlap the bar.

The problem is that UIWebView appears not to be a proper subclass of UIScrollView; thus, I can't use setContentOffset. Does anyone have any tips or tricks on getting a UIWebView to look good with a translucent navigation bar? Thanks.

Jonathan Sterling
  • 18,320
  • 12
  • 67
  • 79

6 Answers6

9

As of iOS 5 you can use the scrollView property of UIWebView, and set a contentInset to adjust the positon.

CGFloat top = 0.0;

if( self.navigationController != nil && self.navigationController.navigationBar.translucent ) {
    top = self.navigationController.navigationBar.bounds.size.height;
}

UIWebView* wv = ...

wv.scrollView.contentInset = UIEdgeInsetsMake(top, 0.0, 0.0, 0.0);
zeroimpl
  • 2,746
  • 22
  • 19
  • I recommend using this for iOS 5. In the case of iOS 4, you can iterate the subviews to find the view where isKindOfClass: returns true for [UIScrollView class]. Then just set the contentInset on this view (cast to a UIScrollView). – Prometheus Feb 13 '12 at 19:18
  • This looks like the proper solution to me. – bio Jul 12 '15 at 16:59
3

The easiest way is to set:

webView.clipsToBounds = NO;
webView.scrollView.clipsToBounds = NO;

It work on bouth iOS 7 & 6, and I didn't try, but on iOS 5 probably too

Friend_LGA
  • 71
  • 2
2

I achieved this by setting the UIWebView subviews to not clip to bounds, then I could put a toolbar on top of it and get the desired effect:

for (UIView *subview in theWebView.subviews) {
    subview.clipsToBounds = NO;
}
Brandon
  • 953
  • 10
  • 12
0

I am not sure if there is a clean method to doing this. I have not tried it, but here is an idea:

  1. draw the uiwebview at origin 0,0
  2. intercept all screen touches
  3. if you detect the user dragging up (scrolling up the webview), dont pass the touch on
  4. Instead, move the webview up x pixels so its origin is (0,-x). Then change the height to add x pixels
  5. Youy will need to keep some sort of state so that you know when to stop resizing the webview and start passing on the touches so the webview will scroll.

Getting it back is the same only you do it on a drag down (scrolling down the webview).

coneybeare
  • 33,113
  • 21
  • 131
  • 183
  • How do you do the part 'don't pass the touch to uiwebview' ? – dotnetcoder Oct 12 '11 at 03:43
  • This is probably not the easiest way to achieve this, especially if you're targeting iOS 5+ (UIWebView scrollView.contentInset accomplishes this cleanly). See the answer by zerotool. For iOS 4, you can iterate the UIWebview subviews to reliably access the same UIScrollView. – Prometheus Feb 13 '12 at 19:21
  • This is a very very old q and a – coneybeare Feb 13 '12 at 21:21
0

Another way to possibly do this is to insert a div in the html code you are rendering so that it is spaced out up on the top of the page. make sure you set your zoom correctly and set the uiwebviews origin to (0, -x) to begin with.

coneybeare
  • 33,113
  • 21
  • 131
  • 183
0

With the advent of iOS 7, the offset height would now need to include the height of the top status area. Otherwise, iOS7 devices will have 20 pixels of webview still hidden under the navigation bar.

In a project that needs to support iOS 7 and older devices, a macro like the one found here:

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

Can be very useful. A modified version of zerotool's helpful code listed above could now look something like this:

if (self.navigationController != nil && self.navigationController.navigationBar.translucent) {
    top = self.navigationController.navigationBar.bounds.size.height;
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
        top += [[UIScreen mainScreen] applicationFrame].origin.y;
    }
}
// (etc.)
Community
  • 1
  • 1
Mark Semsel
  • 7,125
  • 3
  • 29
  • 27