UIWebview won't zoom even after setting scalesPageToFit to YES - iphone

I have a UIWebview that is loaded as a subview when a user selects a tab on a UISegmentedControl. For some reason, I can not get it to allow pinch/zooming.
I set the following code in the viewDidLoad: method, so it should work.
self.myWebView = [[[UIWebView alloc] initWithFrame:self.view.frame] autorelease];
self.myWebView.backgroundColor = [UIColor whiteColor];
self.myWebView.scalesPageToFit = YES;
self.myWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
self.myWebView.delegate = self;
[self.view addSubview: myWebView];
I tried loading a UIWebView from a NIB and creating it programmatically with no avail. Is there something I'm missing? What could be causing the webview to ignore pinching and zooming?
Thanks!

[webView stringByEvaluatingJavaScriptFromString:#"document.body.style.zoom = 5.0;"];
seem to be the suitable solution

I solved this with setting a view port:
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.5; user-scalable=1"/>
Good luck

I see you are setting the autoresizingMask. Does that mean you have created the UIWebView with an initial size of CGRectZero ? Can you interact with the document at all? I mean, does scrolling/tapping work?

In my experience, you need to set scalesPageToFit before the UIWebView loads. This means setting before viewDidLoad etc. What I do is set it in "shouldStartLoadWithRequest"
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//make sure that the page scales when it is loaded :-)
theWebView.scalesPageToFit = YES;
return YES;
}
My interpretation of the documentation is that the scalesPageToFit property dictates how the page WILL be loaded. It does not alter things after the fact.
Hope this helps.

FYI:
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.5; user-scalable=1"/>
works but
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.5; user-scalable=YES"/>
does not on the iPhone. The documentation says to use yes/no. I guess case matters in this case. In obj-c the values are YES/NO and 1/0

You have to enable multi-touch. Pinch involves more than one finger on the screen:
[myWebView setMultipleTouchEnabled:YES]

This is what Apple suggests in the webview class reference.
Important: You should not embed UIWebView or UITableView objects in UIScrollView objects. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.

Related

UIWebView/Subview Constraint Issue

Okay - So I've read the "Removing and Re-Adding a subview with autolayout" but I still can't seem to figure out whats going on. I have a UIWebview within my application that prompts upon clicking on a date within a calendar UI. When I click on the first field of the subview "Enter Name", It automatically moves the entire screen and focus to the "Notes" field and the user cannot see any other field. (Id post a picture but I don't have reputation enough yet) There are a few other fields after this in which respond the same way. Check boxes are fine and do not cause an issue. I know that I haven't added any constraints to this subview so I am figuring I need to . I just don't know where to start.
I recently migrated the app to autolayout and everything works great, with the exception of this subview.
The WebUI is responsive in that it adjusts according to the screen/window size so that is not the issue.
Below is my UIWebView subview that loads the URL
- (void)viewDidLoad
{
[super viewDidLoad];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *gymString =[prefs stringForKey:#"name_preference"];
[prefs synchronize];
[logView addSubview: activityIndicator];
[logView setBackgroundColor:[UIColor clearColor]];
[logView setOpaque:NO];
[logView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.MYWEBSITE.com/mobiletracking?gym=%#", gymString]]]];
timer = [NSTimer scheduledTimerWithTimeInterval:(1.0/2.0) target:self selector:#selector(loading) userInfo:nil repeats:YES];
}
Any thoughts or insight would be greatly appreciated.
Ahhh... Found it. It was within my personal template, meta viewport settings
I had to replace:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0">
With this:
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, target-densityDpi=device-dpi" />
Fixed: :) - iOS 7 Compatibility.

Webview content not resizing

I have a webview.. with the following attributes:
1.scalesPageToFit
2.Autoresizing masks
3.contentmode = aspectFit
After loading it fits to the page as obvious. But as soon as i zoom in and then zoom out to normal; rotating the device doesn't fit completely.
As a tweak, i have checked if the orientation mode is landscape reload the web page. I read various posts in this regard, but couldn't find any solution.
You have 2 folowing options:
Add this into head section of your html file:
<meta name="viewport" content="width=device-width" />
Or call [myWebView reload] when orientation changes
You can use this Code
NSString *website =#"http://www.google.com";
NSURL *url = [NSURL URLWithString:website];
NSURLRequest *requestURL =[NSURLRequest requestWithURL:url];
mywebview.scalesPageToFit = YES;
mywebview.autoresizesSubviews = YES;
[mywebview loadRequest:requestURL];
It took more than 2 days to find out the reason causing this issue. Actually webview was working correctly except the fact that if you try to use PinchGesture to zoom out further.. webview will baheve in the same way.
To overcome this issue, we need to set the zoom scale of scroll view in Webview under willRotate method. However, it's animating weirdly but one can make a guess where the issue lies.

uiwebview youtube starting in landscape thumbnail does resize on rotation

I have navigation controller with a tableview. When you click on one of the cells it pushes on a view with a uiwebview on it. You are taken to a YouTube page.
When you are on the table view in portrait and click on a cell you see the youtube page in portrait. Changing your orientation the video thumbnail does not refresh. So the thumbnail is smaller. This is fine. I actually prefer it smaller. All the content that would consume 2 lines will then consume 1 line. So in other words everything else adjusts for the new dimensions.
The problem comes in when you start off in landscape. Since the thumbnail doesn't resize on orientation change, changing to portrait mode, the image now goes off the screen, while the rest of the content adjusts correctly.
[webVIew refresh];
does work but it obviously loads the entire page again. So depending on the connection there will be a flicker or possibly the site will go white until its finished loading (on slower connections).
I also tried load the website in an iframe. I asked a similar question yesterday, this was for local pages i was creating. The answer to that question was to put <meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0;'> in the head. So I tried that with an iframe going and getting the page. That seemed like a dumb hack to begin with, but i was willing to go there. It wouldn't even load the page at all. I guess because the youtube page i'm loading redirects to yet other page. Upon further research it seemed like there were other issues with the iframe such as scrolling.
So my question is how can i:
A. Get just the thumbnail to resize/reload on orientation change
OR
B. Get the thumbnail to load in the dimensions it would load in portrait mode all the time, even if it was started in landscape.
You should override this method in your UIViewController class and do the resizing there:
(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
I found the answer, maybe someone could explain it or offer a better solution. There was also an addition bug that I had to work out.
I made sure the uiwebview had the delegate set to files owner.
I changed the parent view when it pushed the view onto the form from:
[self.navigationController pushViewController:controller animated:YES];
to (the important part being the 320, i'm restricting the view to portrait):
[self.navigationController pushViewController:controller animated:YES];
controller.webView.hidden = YES;
controller.webView.frame=CGRectMake(0, 0, 320,367);
3.On the webview i load the url as i always did:
NSURL *url = [NSURL URLWithString:sUrl];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
4.In the webviewdidfinishload i now have:
if (self.interfaceOrientation ==
UIInterfaceOrientationLandscapeLeft ||
self.interfaceOrientation ==
UIInterfaceOrientationLandscapeRight) {
self.webView.frame=CGRectMake(0, 0, 480,227);
}
self.webView.hidden = NO;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
All this would normally have solved my issue, but then i found out that the gdata url i'm getting from youtube service actually gets resolved to a 2nd url. Then i guess youtube changed their url format so it is forwarded to a 3rd url. This means that my didfinishload code was being called before the final url had loaded. To solve this i added:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[[NSString stringWithFormat:#"%#",request.URL] substringWithRange:NSMakeRange(0, 26)] isEqualToString:#"http://m.youtube.com/watch"]) {
NSString *sUrl=[NSString stringWithFormat:#"%#",request.URL];
sUrl = [sUrl stringByReplacingOccurrencesOfString:#"http://m.youtube.com/watch?" withString:#"http://m.youtube.com/#/watch?"];
NSURL *url = [NSURL URLWithString:sUrl];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestObj];
return NO;
}
//NSLog(#"request:%#",request.URL);
return YES;
}
Which im sure could be better but basically i tell it to ignore the 2nd url, and make my own change to go to the 3rd url.

Allowing user to pinch zoom in/out of a webview

I have a WebView into which I'm loading a local HTML page with some embedded images. I want to allow the user to zoom in on the text and image in a similar fashion as they would with the web browser.
Any ideas how to enable this?
Thanks
Try to set UIWebView property scalesPageToFit to YES
For completeness. You must enable multitouch, scalesPagesToFit to get it to work (there are some conditions if its within certain other views).
But then to prevent it scaling your webpage (especially if using local files). You will need to add the following snippet to your HTML
For more info so: http://iphoneincubator.com/blog/windows-views/right-scale-for-a-uiwebview
This is the code that works for me:
// declare and allocate UIWebView before
// UIWebView *webView;
// webView = [[UIWebView alloc] initWithFrame:CGRectMake(x, y, w, h)];
webView.scalesPageToFit = YES;
I used scalesPageToFit to YES.... it allows it to zoom in some... but not a true zoom like safari has.

iPhone OS: Tap status bar to scroll to top doesn't work after remove/add back

Using this method to hide the status bar:
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
When setting "hidden" back to NO, the tap-to-scroll-to-top (in UIWebView, UITableView, whatever) doesn't work any more, and requires a restart of the app to get the functionality back.
Is this a bug (I filed a rdar anyhow) or have I missed a step? Should I perhaps expect this behavior since the statusBar "loses touch" somehow with the respective view?
You could try setting the ScrollsToTop property to true again after re-showing it:
[currentView setScrollsToTop:YES];
If that's not working, are you definitely only showing one view? If there is more than one scrolling view a scrollViewDidScrollToTop message is ignored...
In iOS 5.0 you can access the scrollview property of the UIWebView
webView.scrollView.scrollsToTop = YES;
The following fix by Alex worked for me. Thanks!
((UIScrollView *)[[webView subviews] objectAtIndex:0]).scrollsToTop = NO;
Being in a hurry this fix worked great, however given more time I might've subclassed the UIWebView and accessed the protected UIScrollView member directly.
The worry I have with Alex' method is that it assumes that UIScrollView is at index zero of the subviews (encapsulation allows private members to change). Which suggests another solution still:
for (UIView* v in [webView subviews])
{
if ([v isKindOfClass:[UIScrollView class]])
{
(UIScrollView *)v.scrollsToTop = NO;
}
}
I was having a similar problem where the scroll-to-top functionality was lost. Turns out this will only work when you have only one active view at a time (within the same scroll view). In my case I had a table view and another view which would fade in/out. Adding a removeFromSuperview at the end of the animation did the trick.
The answer was in the UIScrollView.h file comments:
/*
this is for the scroll to top gesture. by default, a single scroll visible scroll view with this flag set will get the call. if there is more than one visible with this
flag set or the delegeat method returns NO, the view isn't scrolled
*/
#property(nonatomic) BOOL scrollsToTop; // default is YES. if set, special gesture will scroll to top of view after consulting delegate
You can use the following code to have the UIWebView ignore scrollToTop without the extra UIScrollView:
((UIScrollView *)[[webView valueForKey:#"_internal"] valueForKey:#"scroller"]).scrollsToTop = NO;
I had a similar problem after playing a Youtube video within my app. scrollsToTop was still set to YES but tapping the status bar had no effect.
I finally realised that my app window was no longer the key window. After adding the following line to a UIWindow subclass (which I already had for other reasons) everything worked as it should again:
if (![self isKeyWindow]) [self makeKeyWindow];
I just ran across a similar behavior in the app I'm currently working on. In its case, if you load a YouTube video from within a UIWebView, scroll to top stops working for the rest of the application's life cycle. I kind of assume this might happen after loading the movie player as well, but haven't confirmed. That functionality has been around a lot longer and probably has fewer bugs.
When there are multiple scrollview, you can also set scrollUpToTop to NO for the others scrollview. cf:
setScrollsToTop with multiple UIScrollView classes and/or subclasses(UITableView)
I want to add my case, I add an UIWebView on an UIScrollView, as h4xxr had answered on the top:
If there is more than one scrolling view a scrollViewDidScrollToTop message is ignored
So, I get a simply way to make it work on webView: just set the scrollView·s scrollsToTop property false.
And when tap the status bar, it won`t got intercepted by the scrollView, and the webView scrolls to the top!
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.frame = self.view.bounds;
scrollView.scrollsToTop = false; //igore scrollView`s scrollsToTop
[self.view addSubview:scrollView];
UIWebView *webView = [[UIWebView alloc] init];
webView.frame = scrollView.bounds;
[scrollView addSubview:webView];