PDA

View Full Version : onOrientationChange event is not being handled properly on ip* devices by uiwebview



yuryb
14 Sep 2010, 9:43 PM
you're probably aware of this problem, but:
onOrientationChange event is not being properly handled by the iPhone sdk's component UIWebView, which is basically a built-in "safari" browser and is being used in all ip* apps where the browser functionality is needed.
due to this problem, none of the sencha touch demos are working properly if opened in any other browser than the native safari on ip*s: programmatic ui changes which has to happen on orientation change are not happening.
to see the problem, run kitchen sink in any 3-rd party browsers you can get from the apple's app store (atomic web, mercury, ilunascape, ifindz to name a few). the problem is especially severe on ipad.
do you have any suggestions what can be done to fix/work around this problem?
i'm ready to publish an app written in sencha (great great framework, btw, thank you!), and that is the only reason for the delay.
any help would be greatly appreciated.
thank you in advance,
yury

evant
15 Sep 2010, 1:26 AM
So why do you say this is a bug in Touch? If the browser doesn't support the orientationchange event like it should, there isn't really much we can do about it.

As a side note, it doesn't seem to support local urls (http://10.0.0.2), what a waste of a dollar! ;)

yuryb
15 Sep 2010, 8:51 AM
here is why i said it is still a sencha problem:
-- i've put some js function call into my iOS code to call the page loaded into uiwebview when device orientation changes;
-- in this call i was trying to call sencha's layout routines: doLayout(), etc;
-- ui goes crazy in this case, due to the fact that some internal values in the sencha's layout engine are off and in dis-array; for instance Ext.orientation returns 'portret' in landscape, but screen dimensions look like landscape's;
-- i tried to follow some suggestions on this board and go through a "window resize" rout. it produced sporadic success/failure results on kitchen sink: sometimes ui re-renders properly, and some times - some elements are off-screen and/or have wrong sizes.

please do not be offensive, i truly love your product!
i just need some sort of suggestion from people who knows how the stuff works inside :-))

as of now, the only stable (but soooooo ugly) solution is to call 'document.location = document.location' on each orientation change, which works fine, just... not cool at all :-((

please help if you can.
thanks again.

(btw, i've purchased sencha-touch license a couple of days ago)

yuryb
16 Sep 2010, 4:25 PM
please respond - i need to know what can be done!
thank you...

evant
16 Sep 2010, 4:41 PM
Again, back to the original point, why doesn't the browser fire the orientationchange event? We can only react to the events made available. Have you talked with the developers of the browser?

iame.wang
17 Sep 2010, 2:28 AM
when orientation changed:

UIWebView.stringByEvaluatingJavaScriptFromString("var e = document.createEvent('Events'); e.initEvent('orientationchange', true, false); document.dispatchEvent(e); ");

sencha touch will work

yuryb
17 Sep 2010, 7:35 AM
thank you very much!
your solution resolved the problem!

lieselbr
27 Sep 2010, 5:19 AM
when orientation changed:

UIWebView.stringByEvaluatingJavaScriptFromString("var e = document.createEvent('Events'); e.initEvent('orientationchange', true, false); document.dispatchEvent(e); ");

sencha touch will work

Hi, this line of code i have to use it inside xcode?

milo08
27 Sep 2010, 6:09 AM
Hi lieselbr,

yes you have to do this in the ViewController from your UIWebView, in the didRotateFromInterfaceOrientation function.



- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[yourWebview stringByEvaluatingJavaScriptFromString:@"var e = document.createEvent('Events'); e.initEvent('orientationchange', true, false); document.dispatchEvent(e); "];
}


that works, but in my tests is very slow. I don`t know its my app, i will test it.

greetz

milo

lieselbr
27 Sep 2010, 6:23 AM
Thanks man work just fine for me =D>

wingfeng
25 Feb 2011, 10:42 PM
Hi lieselbr,

yes you have to do this in the ViewController from your UIWebView, in the didRotateFromInterfaceOrientation function.



- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[yourWebview stringByEvaluatingJavaScriptFromString:@"var e = document.createEvent('Events'); e.initEvent('orientationchange', true, false); document.dispatchEvent(e); "];
}


that works, but in my tests is very slow. I don`t know its my app, i will test it.

greetz

milo

It didn't work in sencha 1.0.1a and iOS 4.2.1 UIWebView

RandyMcMillan
15 Mar 2011, 11:05 PM
/*
* PhoneGap is available under *either* the terms of the modified BSD license *or* the
* MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
*
* Copyright (c) 2005-2010, Nitobi Software Inc.
*/


#import "PhoneGapViewController.h"
#import "PhoneGapDelegate.h"

@implementation PhoneGapViewController

@synthesize supportedOrientations, webView;

- (id) init
{
if (self = [super init]) {
// do other init here
}

return self;
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation
{
BOOL autoRotate = [self.supportedOrientations count] > 1; // autorotate if only more than 1 orientation supported
if (autoRotate)
{
if ([self.supportedOrientations containsObject:
[NSNumber numberWithInt:interfaceOrientation]]) {
return YES;
}
}

return NO;
}

/**
Called by UIKit when the device starts to rotate to a new orientation. This fires the \c setOrientation
method on the Orientation object in JavaScript. Look at the JavaScript documentation for more information.
*/
- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation duration: (NSTimeInterval)duration {
double i = 0;
switch (toInterfaceOrientation){
case UIInterfaceOrientationPortrait:
i = 0;
break;
case UIInterfaceOrientationPortraitUpsideDown:
i = 180;
break;
case UIInterfaceOrientationLandscapeLeft:
i = 90;
break;
case UIInterfaceOrientationLandscapeRight:
i = -90;
break;
}
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"navigator.orientation.setOrientation(%f);", i]];

////// trigger orientationchange inUIWebView for SenchaTouch
[webView stringByEvaluatingJavaScriptFromString:@"var e = document.createEvent('Events'); e.initEvent('orientationchange', true, false); document.dispatchEvent(e); "];


}

- (void) setWebView:(UIWebView*) theWebView {
webView = theWebView;
}

@end

wingfeng
17 Mar 2011, 12:17 AM
Thanks it works!

rdp
22 Mar 2011, 3:57 AM
Sorry, but I can't setup this code in my project, maybe 'cause I don't know objective-c?

I received an error because supportedOrientations e webView are not defined. Where I must define them? And what type are these vars?

thanks :)

danmux
18 Apr 2011, 5:13 PM
There has been a fix committed for this in github...

https://github.com/phonegap/phonegap-iphone/commit/7c93856fdc4e8faef30de68e616761b89e3b4395#commitcomment-348170

but it does not quite work because it only calls window.onorientationchange() and does not create the event as above

trkaky
5 Aug 2011, 4:08 AM
Thanks for the code partly solved my problem but Ext.Viewport.orientation always returns 'Portrait' even if its not.

Any idea?

Thanks

trkaky
5 Aug 2011, 4:58 AM
Solved


- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
switch (toInterfaceOrientation)
{
case UIDeviceOrientationPortrait:
[webView stringByEvaluatingJavaScriptFromString:@"window.__defineGetter__('orientation',function(){return 0;});window.onorientationchange();"];
break;
case UIDeviceOrientationLandscapeLeft:
[webView stringByEvaluatingJavaScriptFromString:@"window.__defineGetter__('orientation',function(){return 90;});window.onorientationchange();"];
break;
case UIDeviceOrientationLandscapeRight:
[webView stringByEvaluatingJavaScriptFromString:@"window.__defineGetter__('orientation',function(){return -90;});window.onorientationchange();"];
break;
case UIDeviceOrientationPortraitUpsideDown:
[webView stringByEvaluatingJavaScriptFromString:@"window.__defineGetter__('orientation',function(){return 180;});window.onorientationchange();"];
break;
default:
break;
}
}