Remove gradient background from UIWebView?
Asked Answered
C

8

36

How do remove the gradient from a UIWebView - the one that you see if you overscroll the top or bottom. This code

webView.backgroundColor = [UIColor whiteColor];

just changes the color of the gradient, it doesn't removes it. How can this be done?

(note: not the same question as UIWebView underside)

Cecilycecity answered 9/6, 2010 at 19:12 Comment(3)
I would like to find this out too, as that would make the bounce look nice in a UIWebView...Foxtail
Yes, this is most annoying, I'd also be interested in a solutionAssyriology
possible duplicate of Remove UIWebView Shadow?Tolbert
A
82

Aha, yes terminology fail. I wouldn't call that a shadow at all, but c'est la vie. Here is my type-safe code to achieve the effect. To summarise: this will hide any image-view children of the scroll view. It's not as vulnerable to change as the (objectAtIndex:0) methods, so if Apple re-order the children of the webView control it will work fine, but still relies on the fact that the gradient effect is applied by imageviews parented to the scroll view (and that there is indeed a scrollview underpinning the web view).

{
    webView.backgroundColor = [UIColor whiteColor];
    for (UIView* subView in [webView subviews])
    {
        if ([subView isKindOfClass:[UIScrollView class]]) {
            for (UIView* shadowView in [subView subviews])
            {
                if ([shadowView isKindOfClass:[UIImageView class]]) {
                    [shadowView setHidden:YES];
                }
            }
        }
    }
}
Assyriology answered 12/11, 2010 at 16:53 Comment(3)
You wouldn't call it a shadow? Certainly it is implemented by drawing a gradient, but the purpose is to make the webview appear to float over the background. So I will still call it a shadow :-)Lithium
That's fair enough. :-) Bounty awarded for linking the question, although should this one perhaps be closed as a duplicate?Assyriology
Still works (6.1) but I find setting the backgroundColor is not necessary. Also, now that we have access to the webView.scrollView we can rewrite as: for (UIView *shadowView in [webView.scrollView subviews]) { if ([shadowView isKindOfClass:[UIImageView class]]) { [shadowView setHidden:YES]; } }Latrice
O
3

To transparent the UIWebView and remove the scrolls.

 webView.opaque = NO;
 webView.backgroundColor = [UIColor clearColor];
 for(UIView *view in webView.subviews){      
      if ([view isKindOfClass:[UIImageView class]]) {
           // to transparent 
           [view removeFromSuperview];
      }
      if ([view isKindOfClass:[UIScrollView class]]) {
           UIScrollView *sView = (UIScrollView *)view;
           for (UIView* shadowView in [sView subviews]){
                //to remove shadow
                if ([shadowView isKindOfClass:[UIImageView class]]) {
                     [shadowView setHidden:YES];
                }
           }
      }
 }

for hide scroll indicators

Ophiuchus answered 13/6, 2012 at 9:24 Comment(1)
Remember to make sure that any superview of the webview is also transparent :) Then this script will work for youVast
L
2

You mean the shadow? Remove UIWebView Shadow?

Lithium answered 12/11, 2010 at 15:39 Comment(0)
C
1

The only way I found how to do this was :

for(UIView *aView in [[[webView subviews] objectAtIndex:0] subviews]) { 
        if([aView isKindOfClass:[UIImageView class]]) { aView.hidden = YES; } 
}

It just just steps thru the subviews of UIWebView and removes the view if it is an image view.

I haven't put this in any App Store apps, so I don't know if Apple would accept it.

EDIT: Brian's link provides more details.

Cecilycecity answered 12/11, 2010 at 15:55 Comment(0)
T
0

Using method suggested above you won't be able to edit your scroll indicator/insets later. They appear as UIImageView also, so you should check for last object:

            UIView* lastView = [[subView subviews] lastObject];
            for (UIView* shadowView in [subView subviews])
            { 
                if(shadowView!=lastView) ... <-this one is a scroll 
            }
Tambratamburlaine answered 8/10, 2011 at 12:21 Comment(0)
A
0

I was able to do this by adding white subviews to the top and bottom of the WebView’s scrollView. I control the content of the WebView, so I know that white is OK - this won’t work if you are loading arbitrary content.

// _topCover and _bottomCover are ivar UIViews
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    // with cover views 300pt high, I couldn't scroll far enough to see the shadow,
    // even in portrait on an iPad, which gives you the longest scroll distance
    CGFloat coverage = 300;

    _topCover = [[UIView alloc] initWithFrame:CGRectMake(0, -coverage, webView.bounds.size.width, coverage)];
    _bottomCover = [[UIView alloc] initWithFrame:CGRectMake(0, webView.scrollView.contentSize.height, webView.bounds.size.width, coverage)];
    _topCover.backgroundColor = [UIColor whiteColor];
    _bottomCover.backgroundColor = [UIColor whiteColor];

    // in case the webView is resized, e.g. by rotating the device
    _topCover.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
    _bottomCover.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;

    [webView.scrollView addSubview:_topCover];
    [webView.scrollView addSubview:_bottomCover];
}

I run it it after the page loads so that webView.scrollView.contentSize.height will give me the correct height. I’m not sure how this will work if your pages are dynamically changing height. My page loads only once; if yours is reloading, you will want to skip running alloc/init on _topCover and _bottomCover after the first time for efficiency.

Update: I’m not sure that my use of autoresizingMask, above, is sufficient when the view rotates. You may need to put this in the UIViewController that contains your UIWebView to resize the covers after rotating:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{        
    CGFloat coverage = 300;
    _topCover.frame = CGRectMake(0, -coverage, self.webView.bounds.size.width, coverage);
    _bottomCover.frame = CGRectMake(0, self.webView.scrollView.contentSize.height, self.webView.bounds.size.width, coverage);
}
Archbishop answered 8/10, 2012 at 4:0 Comment(0)
V
0

I've built upon @damithH 's answer

@implementation UIWebView (Extensions)

- (void)setBackgroundAndShadowVisible:(BOOL)visible
{
    self.opaque = !visible;
    self.backgroundColor = [self.backgroundColor colorWithAlphaComponent:visible ? 1.0 : 0.0];
    for(UIView *view in [self subviews])
    {
        if([view isKindOfClass:[UIImageView class]])
        {
            view.hidden = !visible;
        }
        if([view isKindOfClass:[UIScrollView class]])
        {
            UIScrollView *scrollView = (UIScrollView *)view;
            for (UIView *shadowView in [scrollView subviews])
            {
                if ([shadowView isKindOfClass:[UIImageView class]])
                {
                    shadowView.hidden = !visible;
                }
            }
        }
    }
}

@end
Vast answered 23/1, 2013 at 12:3 Comment(0)
H
0
if (UIDevice.currentDevice.systemVersion.intValue < 7)
    for (UIImageView *imageView in webView.scrollView.subviews)
        if ([imageView isKindOfClass:[UIImageView class]] && imageView.image.size.width == 1)
            imageView.hidden = YES;
Hosanna answered 18/6, 2014 at 9:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.