Full Source code: http://github.com/boctor/idev-recipes/tree/master/TransparentUIWebViews
Problem:
UIWebViews have a built in gradient at the top and bottom.
If you set the UIWebView’s background color to clearColor, this gradient is still visible.
How can we turn off this gradient to make the UIWebView completely transparent?
Solution:
The UIWebView API doesn’t expose this gradient, but we can be sneaky and look at it’s view hierarchy.
If we put a breakpoint in the debugger where we have access to a UIWebView then in the console’s gdb prompt, we can take a look at the view hierarchy:
(gdb) po [webView recursiveDescription] <UIWebView: 0x68220e0; frame = (0 0; 320 460); > | <UIScrollView: 0x4b2bee0; frame = (0 0; 320 460); > | | <UIImageView: 0x4b2dca0; frame = (0 0; 54 54); > | | <UIImageView: 0x4b2da20; frame = (0 0; 54 54); > | | <UIImageView: 0x4b2d9c0; frame = (0 0; 54 54); > | | <UIImageView: 0x4b12030; frame = (0 0; 54 54) > | | <UIImageView: 0x4b11fd0; frame = (-14.5 14.5; 30 1); > | | <UIImageView: 0x4b11f70; frame = (-14.5 14.5; 30 1); > | | <UIImageView: 0x4b11f10; frame = (0 0; 1 30); > | | <UIImageView: 0x4b11eb0; frame = (0 0; 1 30); > | | <UIImageView: 0x4b11e50; frame = (0 430; 320 30); > | | <UIImageView: 0x4b2d0c0; frame = (0 0; 320 30); > | | <UIWebBrowserView: 0x6005800; frame = (0 0; 320 460); >
So a UIScrollView contains a UIBrowserView filling up the UIWebView which we can assume is the actual web view and then a bunch of UIImageViews at the top and bottom are used to show the gradients. So how do we hide them?
This hierarchy may well change in future iOS versions, so the less assumptions we make the better. We shouldn’t assume that there is a UIScrollView with embedded UIImageViews, but we do have to make at least one assumption: That the only UIImageViews are the ones used for the gradients.
So how do we find all the UIImageViews and hide them? A view can contain any number of subviews, so we need to walk the view hierarchy and hide any UIImageViews we find. To be safe, we should do this before we load the UIWebView with any content.
- (void)viewDidLoad { [super viewDidLoad]; [webView setBackgroundColor:[UIColor clearColor]]; [self hideGradientBackground:webView]; } - (void) hideGradientBackground:(UIView*)theView { for (UIView* subview in theView.subviews) { if ([subview isKindOfClass:[UIImageView class]]) subview.hidden = YES; [self hideGradientBackground:subview]; }
Full Source code: http://github.com/boctor/idev-recipes/tree/master/TransparentUIWebViews
If you think think this is something that Apple should provide an API for, then please fill out an enhancement request at http://bugreport.apple.com
w = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 300)];
//remove shadows from web view 😉
for (int x = 0; x < 10; ++x) {
[[[[[w subviews] objectAtIndex:0] subviews] objectAtIndex:x] setHidden:YES];
}
There are a number of things wrong with this solution:
1) it assumes that the web view has at least 10 subviews of it’s first ubview. If the implementation changes so that there are less than 10, it will crash.
2) it assumes that the subview that we need to change us at index 0. That could easily change in the future.
3) it blindly hides all subviews of this object without checking if they are a UIImageView or not.
The article has a much better solution. It’s more clear and makes less assumptions.
it is use ful
thank u very much
Here is a more reliable method (I think) that adds subviews on top of the web view. Only works if you control the content of the web view, or detect what color it is and make the cover views match.
[…] the background color of the UIWebView to avoid a “color flash” while it loads, and for removing the top and bottom shadow that appear when “overscrolling” the web view, but I haven’t seen anyone address […]
[…] the background color of the UIWebView to avoid a “color flash” while it loads, and for removing the top and bottom shadow that appear when “overscrolling” the web view, but I haven’t seen anyone address […]
[…] the background color of the UIWebView to avoid a “color flash” while it loads, and for removing the top and bottom shadow that appear when “overscrolling” the web view, but I haven’t seen anyone address […]