UIWEBVIEW +contents fit in frame of webview - iphone

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
}

Related

Change the height of the UIWebView according to the content size

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.

UIWebView disable zooming when scalesPageToFit is ON

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];

UIWebView auto rotation corrupts web view content (screenshots inside)

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;"];
}

How to reset UIWebView's zoom? I'm already using scalesPagesToFit = YES;

I've been looking for the past week for the answer to this question.
I have a UIWebView, inside of a UIScrollView. Everything works great, but I want the content of the UIWebView to reset its zoom, when the orientation changes.
In the HTML inside the UIWebView, I set the width of the viewport (w/ a meta tag) to "device-width" and then on the Obj-C side, I set the scalesPagesToFit = YES;
I've tried resetting the zoom with javascript; by replacing the meta tags in runtime; reloading; accessing the UIScrollView inside of the UIWebView; etc...
but with no success.
Any of you gods know a workaround?
The only one I can think off is to recreate the UIWebViews every time we change the orientation, but that makes them flash to white whilst rendering content, which looks terrible :(
Any thoughts?
Many thanks,
Andre
I'm just guessing here and haven't tried, but AFAIK a UIWebView has a UIScrollView child. So one should be able to do:
for (UIScrollView *scroll in [myWebView subviews]) {
// Make sure it really is a scroll view and reset the zoom scale.
if ([scroll respondsToSelector:#selector(setZoomScale:)])
[scroll setZoomScale:1.0];
}
On iOS 5+ you have access to scrollView.
Just do:
[webView.scrollView setZoomScale:1.0];
If you want to do it programmatically this is the only way I could find to accomplish it: (specify your own sizes if you wish, i was attempting to zoom out after typing into a form field)
UIScrollView *sv = [[webViewView subviews] objectAtIndex:0];
[sv zoomToRect:CGRectMake(0, 0, sv.contentSize.width, sv.contentSize.height) animated:YES];
Update:
Downscaling wasn't working properly when using
[[[webView subviews] lastObject] setZoomScale:0.25];
The quality of the images being downscaled on the page was awful. Doing:
[[[webView subviews] lastObject] setZoomScale:0.25 animated:YES];
Fixed it. So that last line is the one you could use.
webView was subclassed of a UIWebView which lies on some IB file. I didn't use the Viewport at all. I find that one should pick by either doing this from the Cocoa Touch side or use JS.
I used:
webView.scalesPageToFit = YES;
I wonder if there's a way of resetting the scalesPageToFit.
Adapting from Captnwalker1's answer, I came up with this:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if(toInterfaceOrientation ==UIInterfaceOrientationPortrait||toInterfaceOrientation==UIInterfaceOrientationMaskPortraitUpsideDown)
{
currentScrollView = [[webView subviews] objectAtIndex:0];
[currentScrollView zoomToRect:CGRectMake(0, 0, currentScrollView.contentSize.width, currentScrollView.contentSize.height) animated:NO];
}
else
{
currentScrollView = [[webView subviews] objectAtIndex:0];
[currentScrollView zoomToRect:CGRectMake(0, 0, currentScrollView.contentSize.width, currentScrollView.contentSize.height) animated:NO];
}
}
So load your webview image, and the image will reset it's size when rotated.

iPhone SDK - UIWebView has a grey box over it

Sometimes, my UIWebView will have a grey box over part or all of the content. I can't make heads or tails of why it's happening. It happens regularly for certain content.
Thanks!
--Update--
It seems to occur when the webview is not immediately viewable on the screen -- ie i've got a scrollview, and the webview is below the fold.
--Update #2--
When I bring the content above the fold, it loads fine most of the time. There are still instances when the grey box is still showing up. The weird part is if i double-tap it, it finishes loading the content just fine. bizarre
--Update #3--
Okay, so it seems to be that if my uiwebview has a height greater than 1000px, a grey box appears on the rest of the content below 1000px. A double-tap reveals the actual content.
All UIViews have a size limit of 1024x1024 pixels. This is stated at the end of the Overview section of the UIView documentation.
If your web view must have more than 1024px of content, you will have to take it out of the parent scroll view and let it manage scrolling on its own.
Nudging the UIScrollView in the UIWebView it fixes this for me:
[UIScrollView *webScroller= [[webView subviews] lastObject];
[webScroller setContentOffset:CGPointMake(0,1) animated:NO];
[webScroller setContentOffset:CGPointMake(0,0) animated:NO];
I have been dealing with this glitch as well, and have opened a bug report at apple.
I would have commented above, but I don't have the 50 rep yet.
For anyone else encountering this glitch, send them a report, I included a full project demonstrating it, with a few screenshots from another app I am working on.
The more bug reports they get on a topic, the more likely they are to address it, apparently.
https://bugreport.apple.com/
I've got the same problem. I put a UIWebView inside a big TableViewCell (>1024px) and when I scroll to the bottom of the cell, there is this grey box.
But, if I put a UILabel (also with a big size > 1024px), there is no grey box. So I think this has nothing to do with a max height of a UIView (BTW I can't find anything about this so called 1024 max height). I think it's more a UIWebView issue.
The solution for me is to reload the content of the webview when the grey box appears. Actually, I just have a HTMLString to load so I call [webview loadHTMLstring:] again, and the grey box disappear.
Hope that will help
I found a very intersting post about that, it solved the problem for me :
link ttp://pinchzoom.com/blog/items/view/1386/one-of-the-problems-with-the-uikit-at-the-moment-is-an-issue-embedding-a-uiwebview-within-a-table
Hope that helps
I've used stringByEvaluatingJavaScriptFromString plus moving UIWebView origin.
Design overview: I had a set of controls(UIImage in this example) above(I mean frame.origin.y) UIWebView. So, layout was:
UIView
UIScrollView
UIImageView
UIWebView
Since UIWebView doesn't support scrolling in such hierarchy I've rearrange it like:
UIView
UIScrollView
UIImageView
UIWebView
My view controller is delegate for UIWebViewDelegate and UIScrollViewDelegate.
Then,
- (void)viewDidLoad
{
// set delegates
self.scrollView.delegate = self;
self.webView.delegate = self;
// store original UIWebView position in ivar
webViewPosY = self.webView.frame.origin.y;
// load html into UIWebView
[self.webView loadHTMLString:someHTML baseURL:nil];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
// get UIWebView size and store in ivar
webSize = [self.webView sizeThatFits:CGSizeMake(1.0,1.0)];
// set proper content height for UIScrollView
CGSize contentSize = self.scrollView.contentSize;
contentSize.height = webViewPosY + webSize.height;
self.scrollView.contentSize = contentSize;
// set UIWebView's frame height same as UIScrollView has
CGRect wf = self.webView.frame;
wf.size.height = self.scrollView.frame.size.height;
self.webView.frame = wf;
}
// scrolling logic:
// 1. if origin of UIWebView > 0 then move UIWebView itself
// 2. if origin of UIWebView == 0 then scroll with javascript
// 3. if origin is 0 and whole html is scrolled then move UIWebView again(this happens to support scroll "bouncing", or if you have some views below UIWebView
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat scrollPosY = self.scrollView.contentOffset.y;
// (1) and (2) ifs
// how much to move UIWebView
CGFloat scrollOriginY = (scrollPosY >= webViewPosY) ? webViewPosY : scrollPosY;
// how much to scroll via JS
CGFloat scrollJSY = scrollPosY - scrollOriginY;
// (3) if
if ( scrollPosY > (webSize.height - scrollViewSize.height + webViewPosY ) )
scrollOriginY += scrollPosY - (webSize.height - scrollViewSize.height + webViewPosY);
// scroll with JS
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"document.body.scrollTop = %f;", scrollJSY]];
// move UIWebView itself
CGRect wf = self.webView.frame;
wf.origin.y = webViewPosY - scrollOriginY;
self.webView.frame = wf;
}
This works just fine for me.
I ran into the same issue when dynamically resizing a UIWebView. Here's what worked for me:
#define LAYER_FOR(ui) [(ui) layer]
#define FRAME_FOR(ui) [LAYER_FOR((ui)) frame]
#define SET_FRAME_FOR(ui, frame) [LAYER_FOR((ui)) setFrame: (frame)]
+ (void) setHeightTo: (CGFloat *) height_ptr forView: (UIView *) a_view {
CGFloat height = *height_ptr;
CGRect existing_frame = [[a_view layer] frame];
existing_frame.size.height = height;
// need to reassign the same frame !?
NSLog(#"setting text view: %# to height: %f", a_view, (float) height);
SET_FRAME_FOR(a_view, existing_frame);
}
+ (void) resizeWebView: (UIWebView *) webView {
NSString *js = #" \
var __html_element = document.getElementsByTagName('html')[0]; \
var __height_string = document.defaultView.getComputedStyle(__html_element, null).getPropertyValue('height'); \
__height_string.replace('px', ''); \
";
NSString *heightString = [webView stringByEvaluatingJavaScriptFromString: js];
float height = [heightString floatValue];
if (height != UI_VIEW_HEIGHT(webView)) {
[self setHeightTo: &height forView: webView];
// resize scrollView inside webview to the same height
UIScrollView *webScroller = [[webView subviews] lastObject];
[self setHeightTo: &height forView: webScroller];
}
}
I called this code from webview's delegate 'webViewDidFinishLoad:' method.
Basically, the trick is to resize the webScroller inside webview.
Thanks to Padraig for the suggestion to nudge the webview's subview (the scrollview).