I have a webview which is the top window in the hierarchy and has been declared as shown below. However, it does not scale pages to fit. Pages are top left aligned, but are not scaled, despite the scalesPageToFit property being set to YES. Any help would be greatly appreciated.
webLookupView = [[UIWebView alloc] initWithFrame:CGRectMake(16, 63, 289, 327)];
webLookupView.backgroundColor = [UIColor lightGrayColor];
webLookupView.dataDetectorTypes = UIDataDetectorTypeAll;
webLookupView.scalesPageToFit = YES;
iOS5 gives a better solution
call this from webViewDidFinishLoad
- (void)zoomToFit
{
if ([theWebView respondsToSelector:#selector(scrollView)])
{
UIScrollView *scrollView = [theWebView scrollView];
float zoom = theWebView.bounds.size.width / scrollView.contentSize.width;
scrollView.minimumZoomScale = zoom;
[scrollView setZoomScale:zoom animated:YES];
}
}
I have subsequently discovered that some web pages are correctly scaled, but some are not. For web pages which are not properly scaled, javascript can be used to control zooming as follows:
NSString *jsCommand = [NSString stringWithFormat:#"document.body.style.zoom = 1.5;"];
[webLookupView stringByEvaluatingJavaScriptFromString:jsCommand];
You can use the below code:
self.webView.scalesPageToFit = YES;
self.webView.contentMode = UIViewContentModeScaleAspectFit;
in - (void)webViewDidFinishLoad:(UIWebView *)webView method
or viewDidLoad
If you have access to the html you are loading you can chuck the following meta tag in the header :
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
in Swift2
self.webView.scalesPageToFit = true
self.webView.contentMode = UIViewContentMode.ScaleAspectFit
My solution in swift:
"Scales pages to fit" on webView needs to be checked in interface builder.
Use UIWebViewDelegate.
func webViewDidFinishLoad(webView: UIWebView) {
let zoom = webView.bounds.size.width / webView.scrollView.contentSize.width
webView.scrollView.setZoomScale(zoom, animated: true)
}
As mprivate mentions here you can update the zoom level of the UIWebView.
- (void)webViewDidFinishLoad:(UIWebView *)theWebView {
CGSize contentSize = theWebView.scrollView.contentSize;
CGSize viewSize = theWebView.bounds.size;
float rw = viewSize.width / contentSize.width;
theWebView.scrollView.minimumZoomScale = rw;
theWebView.scrollView.maximumZoomScale = rw;
theWebView.scrollView.zoomScale = rw;
}
Another way of achieving this would be injecting js code on the webViewDidFinishLoad as RunLoop says.
- (void)webViewDidFinishLoad:(UIWebView *)webView {
CGFloat scale = 0.8; // the scale factor that works for you
NSString *js = [NSString stringWithFormat:#"document.body.style.zoom = %f;",scale];
[webView stringByEvaluatingJavaScriptFromString:js];
}
Anybody looking for WKWebView answer, please try the below code:
extension YourViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
webView.evaluateJavaScript(jscript)
}
}
Remember to set the navigationDelegate of the Webview.
For Swift 3, using RunLoop's effective answer:
self.webView.stringByEvaluatingJavaScript(from: "document.body.style.zoom = 1.5;")
In xCode 8.3.3, go to the storyboard of the view/scene where the web view is located and check Scale Page to Fit in the attributes inspector section . Also select Scale to Fill as the content mode.
Try this in your ViewController's viewDidLoad
[self.myWebView setFrame:CGRectMake(self.view.frame.origin.x,
self.view.frame.origin.y,
self.view.frame.size.width,
self.view.frame.size.height)];
I also have the webview set to "scalePageToFit" and viewmode set to "Aspect Fit" in my Storyboard.
There is "Scale To Fit" option in interface builder, so it should be something programatic to do the same.
Related
I am creating a webview to display some text in my app.
CGRect frame = CGRectMake(lblContent.frame.origin.x,
lblContent.frame.origin.y,
lblContent.frame.size.width,
lblContent.frame.size.height);
NSString *htmlText = HTML_DIV_TAG;
htmlText = [htmlText stringByAppendingFormat:#"%#%#", _artistDetail.strContent, #"</div>"];
htmlText = [htmlText stringByReplacingOccurrencesOfString:#"''" withString:#"'"];
UIWebView *webView = [[UIWebView alloc]initWithFrame:frame];
[webView loadHTMLString:htmlText baseURL:nil];
webView.scrollView.bounces = NO;
[self addSubview:webView];
This is the set of codes that i put it in to my app.
But need to adjust the height of the web view according to the content size.
If you set webview.delegate = self you can add the UIWebViewDelegate protocol method webViewDidFinishLoad: and invoke a small bit of javascript to determine the height:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *output = [webview stringByEvaluatingJavaScriptFromString:#"document.body. scrollHeight;"];
NSLog(#"height: %#", output);
}
Another method would be to determine the webView's scrollView contentSize in this method, since that should fit the entire website by the time this method is called.
The only problem with this method, is that this method is called when the page finishes loading. Images are handled differently, which means that the webView might change sizes due to images that finish loading.
try -
float height= [iText sizeWithFont:[UIFont fontWithName:#"FontSpecifiedInTheHtmlText" size: -SpecifiedInHTMLText- constrainedToSize:CGSizeMake(320, 100000)lineBreakMode:UILineBreakModeWordWrap].height;
after u get the height of the content text, u can set the frame/bounds of the WebView.
You may want this:
[webView.scrollView setContentInset:UIEdgeInsetsMake(0, 0, 20, 0)];
UIWebview is scrollable. So when you open a page in UIWebview u need not adjust the height according to the content of the page. You can see all the content by scrolling the UIWebView. You should check that user interaction is enabled for your webview.
I set the UIwebview as a header in UITableview.UIWebview height and width are dynamic.Its come for local html files.
UIWebview and UITableview are under one scroll.
It works fine for iphone.Same method I wrote for ipad it works good.but one problem is there.
In ipad Header view and table view alignment is not proper .
Here is code.
Rootviewcotrollor is UITableviewControllor
Rootviewcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Webview in UITableView";
webview = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 10)]; // Don't use CGRectZero here, won't work
webview.delegate = self;
webview.hidden = YES;
[webview loadRequest:[[NSURLRequest alloc]
initWithURL: [NSURL URLWithString:#"http://www.google.com/"]]];
[self.tableView setTableHeaderView:webview]; // Leave this, else you'll have rows to fill the rest of the screen
}
- (void) webViewDidFinishLoad:(UIWebView *)webView {
float newSize = [[webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.scrollHeight"] floatValue];
NSLog(#"Resizing webview from %.2f to %.2f", webView.frame.size.height, newSize);
webView.frame = CGRectMake(webView.frame.origin.x, webView.frame.origin.y, webView.frame.size.width, newSize);
webView.hidden = NO;
// We need to reset this, else the new frame is not used.
[self.tableView setTableHeaderView:webview];
}
For same code iphone output
And iPad output UITableview start slider ahead of the UIWebview.
I try to set frame of header but it's not working,it give webview and table view both have it's own scrollview which not needed.
What is solution for it?
Thank you.
Its a grouped table view that's why its alignment is not proper cause grouped table view takes some default size from x-origin and y-origin always... you can use plain table or set x of grouped table or increase x-origin of web view..
Have you tried this in your "webviewdidfinishedload" delegate
note that "MyWebView" is the webview that fires the delegate also "webViewHeight" is int value that after it you should add your custom control and it's declared as public this is snap from my working code.. that add uitableview after webview to add comments.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
CGSize size = [MyWebView sizeThatFits: CGSizeMake(1.0f, 1.0f)]; // Pass any size here
CGRect frame = MyWebView.frame;
frame.size.height = size.height;
MyWebView.frame = frame;
webViewHeight = size.height + 200;
}
I am using UIwebview in my project.Where the the cotent in the webview is been filled from html data By doing below code like this:
[webView loadHTMLString:[NSString stringWithFormat:#"<html><body><font face=\"Arial\" size=\"3\"</font>%#</body></html>",[[[dict_Response objectForKey:#"objects"]objectAtIndex:0]objectForKey:#"detaildescription"]] baseURL:[NSURL URLWithString:#"http://newsletter.nobelbiocare.com/"]];
Now i am setting the frame of webview:-
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(appDel.ori_appDel == UIInterfaceOrientationPortraitUpsideDown || appDel.ori_appDel == UIInterfaceOrientationPortrait)
{
webView.frame=CGRectMake(30,150,710,450);
}else{
webView.frame=CGRectMake(30,150,930,450);
}
return yes;
}
Now the thing happen is in Landscape mode the content is showing in proper way.But when i move to portrait mode it automatically shows horizontal scrolling.I dont want to scroll the webview in horizontal mode..
Please help me..How to solve this.
I had used sizetofit and autoresizing|autofixing.
But then also it is not solving Please help me..
#shweta
try to update your webview in webViewDidFinishLoad: this will help you. and try to set the size in html rather than web view frame.
- (void)webViewDidFinishLoad:(UIWebView *)webview {
CGRect oldBounds = [[self webview] bounds];
//in the document you can use your string ... ans set the height
CGFloat height = [[webview stringByEvaluatingJavaScriptFromString:#"document.height"] floatValue];
[webview setBounds:CGRectMake(oldBounds.origin.x, oldBounds.origin.y, oldBounds.size.width, height)];
}
the main concern is the method .
[webview stringByEvaluatingJavaScriptFromString:#"document.height"]
by using javascript.
Instead of
sizetofit and autoresizing|autofixing
Write
webview.scalePageToFit=TRUE
Use this:
[webView loadHTMLString:[NSString stringWithFormat:#"<html><div style='font-family: arial,helvetica;font-size: 14px;'>%#</div></html>",[[[dict_Response objectForKey:#"objects"]objectAtIndex:0]objectForKey:#"detaildescription"]] baseURL:[NSURL URLWithString:#"http://newsletter.nobelbiocare.com/"]];
Try these
1. Put format specifier between body tag as </font>%#</body></html>.
2. Try reloading web view in this
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
//Reload your web view here
}
Is there any way to disable zooming when Scales page to Fit is ON ??
This works for me:
UIScrollView *scrollView = [webView.subviews objectAtIndex:0];
scrollView.delegate = self;//self must be UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return nil;
}
UPDATE: For iOS 5 or higher get scrollView like this:
webview.scrollView.delegate = self;
Instead of using
UIScrollView *scrollView = [webView.subviews objectAtIndex:0];
scrollView.delegate = self;//self must be UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return nil;
}
You can use this:
webview.scrollView.delegate = self;
-(UIView*)viewForZoomingInScrollView:(UIScrollView*)scrollView {
return nil;
}
Second option is better and full-proof. First logic could fail in future SDKs.
There's property called scrollView in UIWebView. Through it you can define this.
To be more specific it should look like this:
myWebView.scrollView.minimumZoomScale = 1.0;
myWebView.scrollView.maximumZoomScale = 1.0;
Edit:
Implement delegate method
- (void)webViewDidFinishLoad:(UIWebView *)webView
For your web view and in it add folowing code:
[webView stringByEvaluatingJavaScriptFromString: #"$('body').bind('touchmove', function(event) { event.preventDefault() });"];
The problem is this also disable the scroll, because it disable the move of touch.
If you want to keep the scroll you have to write a java script that will overwrite the viewport meta tag with:
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
From the Apple Documentation:
scalesPageToFit
A Boolean value determining whether the webpage scales to fit the view
and the user can change the scale.
#property(nonatomic) BOOL scalesPageToFit
Discussion
If YES, the webpage is scaled to fit and the user can zoom in and zoom
out. If NO, user zooming is disabled. The default value is NO.
So if you want to change that behavior, you will probably have to subclass UIWebView.
so it works at me:
NSString *fullURL = #"http://google.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
_webView.scrollView.scrollEnabled = TRUE;
_webView.contentMode = UIViewContentModeScaleAspectFit;
_webView.scalesPageToFit = FALSE;
[_webView loadRequest:requestObj];
i'm having a problem with UIWebView auto-rotating.
the web view straches alright but the content is not.
as you can see in the bottom screenshot there is a black margin, and i know it's the webview since i can see the scrollers when i scroll.
the view controller has:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
the webview has full auto resizing mask, and the view is auto-resizing subviews.
i tried a bunch of tricks from stackoverflow and google but none of them worked.
this happens only on some sites, but if i open the problematic sites in mobile safari or even ios opera browser, it rotates correctly.
EDIT: an example of a problematic site: http://m.calcalist.co.il
the webview is set in the interface builder and loading with this code:
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://m.calcalist.co.il"]]];
scalesPageToFit = YES; // doesn't help
Thanks!
Set the frame in willAnimateRotationToInterfaceOrientation and then set the meta tags.
Also you can set this property of UIWebView:
webView.autoResizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
You can set the web view's scalesPageToFit property to YES.
If you are generating the HTML yourself, then you can also set the viewport meta tag.
If the page has already set the viewport, you can set your viewcontroller to be the web view's delegate and change it like this:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *javaScript = #"var metatags = document.getElementsByTagName('meta'); \
for(cnt = 0; cnt < metatags.length; cnt++) { \
var element = metatags[cnt]; \
if(element.getAttribute('name') == 'viewport') { \
element.setAttribute('content','width = device-width; user-scalable = yes'); \
} \
}";
[webView stringByEvaluatingJavaScriptFromString:javaScript];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if ([self interfaceOrientation] == UIInterfaceOrientationPortrait)
[webView stringByEvaluatingJavaScriptFromString:#"document.body.style.zoom = 1.0;"];
else
[webView stringByEvaluatingJavaScriptFromString:#"document.body.style.zoom = 1.5;"];
}