I\'d like to add a header view to an UIWebView
similar to the address/search bar in MobileSafari and the excellent Articles.app by Sophia Teutschler. More preci
Try this:
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(0, -100, WIN_WIDTH, 100)];
redView.backgroundColor = [UIColor redColor];
self.view.scrollView.contentInset = UIEdgeInsetsMake(100, 0, 0, 0);
[self.view.scrollView addSubview:redView];
NSURLRequest *request = [NSURLRequest requestWithURL: [NSURL URLWithString:@"http://www.baidu.com"]];
[self.view loadRequest:request];
I like AutoLayout specially because I can make the height of the header dynamic.
This is my code using AutoLayout in a controller with a reference 'headerView' to the header view and a 'webView' to the webView.
// Function called in ViewDidLoad:
func addHeaderToWebView(){
// We load the headerView from a Nib
headerView = NSBundle.mainBundle().loadNibNamed(WebViewHeader.nibName, owner: self, options: nil).first as! WebViewHeader
headerView.translatesAutoresizingMaskIntoConstraints = false
webView.scrollView.addSubview(headerView)
// the constraints
let topConstraint = NSLayoutConstraint(item: headerView, attribute: .Bottom, relatedBy: .Equal, toItem: webView.scrollView, attribute: .Top, multiplier: 1, constant: 0)
let leftConstraint = NSLayoutConstraint(item: headerView, attribute: .Leading, relatedBy: .Equal, toItem: webView, attribute: .Leading, multiplier: 1, constant: 0)
let rightConstraint = NSLayoutConstraint(item: headerView, attribute: .Trailing, relatedBy: .Equal, toItem: webView, attribute: .Trailing, multiplier: 1, constant: 0)
// we add the constraints
webView.scrollView.addConstraints([topConstraint])
webView.addConstraints([leftConstraint, rightConstraint])
}
// Function called in viewWillLayoutSubviews: to update the scrollview of the webView content inset
func updateWebViewScrollViewContentInset(){
webView.scrollView.contentInset = UIEdgeInsetsMake(headerView.frame.height, 0, 0, 0)
}
I could not say for sure, but Twitter seems to use UITableView
to achieve this. Perhaps you can try to put your view in the header of the table view, and your content in a cell.
Here is an interesting example you might consider looking at - How to make a Pull-To-Reload TableView just like Tweetie 2
Articles may not be using a UIWebView to display the main article text. To accomplish your task, UIScrollView will be required almost certainly. Resizing its subviews may not be necessary. Check out the UIScrollView code samples provided by Apple.
I think the best solution is to add the header as a subview of your UIWebView’s scrollView, adjust UIEdgeInsets, and in the scrollViewDidScroll delegate function adjust the scrollIndicatorInsets as needed.
Every other solution I found didn't account for the scroll indicators.
Since getting the behavior just right has a bit of complexity to it, I decided to write a class to handle all of it: MMWebViewWithSmartHeader. It's still a little rough around the edges but should help.
After several attemps, I've decided to go with this solution:
Basically I've just added my header UIView as a webview.scrollview subview.
To avoid having the header overlap the browser view:
change its origin.y
here's the code:
CGRect browserCanvas = web.bounds;
for(int i=0; i< [[web.scrollView subviews] count]; i++)
{
UIView* subview = [[web.scrollView subviews] objectAtIndex:i];
CGRect f = subview.frame;
NSLog(@"sub %d -> x:%.0f, y:%.0f, w:%.0f, h:%.0f", i, f.origin.x, f.origin.y, f.size.width, f.size.height);
if(f.origin.x == browserCanvas.origin.x &&
f.origin.y == browserCanvas.origin.y &&
f.size.width == browserCanvas.size.width &&
f.size.height == browserCanvas.size.height)
{
f.origin.y = header.frame.size.height;
subview.frame = f;
}
}
if(![header superview])
{
[web.scrollView addSubview:header];
[web.scrollView bringSubviewToFront:header];
}