Fullscreen + IOS + Cordova + On-screen keyboard + Orientationchange = Trouble

I'm experiencing problems making my application layout scale to fits inside the browser window without leaving unused window real-estate and without overflowing the window.

Basically, the sort of thing you would expect to see if you did:
html, body {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
While it sounds pretty easy, I found it's difficult to achieve. Basically, I want my app to fill that space, and I want to be able to reliably get it's css pixel dimensions, such that I can use JavaScript to lay out the contents of the application within this available space.

Problem is, I'm finding IOS is working *really* hard to break things:
- First of all, it sometimes leaves a gap of 20px below the body tag, or places the top of the body tag below the browser's tabs bar.
- Second, if I change orientation, the iPad gets confused about the size of it's window and offsets the site to the bottom or left and gets it's dimensions wrong.

Depending if the on-screen keyboard is open and/or if I'm running the app in Safari or as Cordova app, the dimensions can be wrong in different ways. In some cases, I have found the WebView or Safari browser to get so hopelessly confused that you need to actually refresh the browser-tab/restart the app to get things lined out properly again.

I would like to find a solution that fixes these problems and works both in Safari browser ánd in Cordova apps on IOS7 and up, for both iPhone and iPad. I don't need a one-size-fits-all solution if that's impossible. Different approaches for different devices, IOS versions or Safari Browser vs. Cordova WebView are perfectly acceptable if needed.

Does anyone have any experience achieving this?

Comments

  • The solution listed here seems to fail if the on-screen keyboard is showing. No keyboard, things work fine, add on-screen keyboard and things will still go bad: http://stackoverflow.com/questions/19012135/ios-7-ipad-safari-landscape-innerheight-outerheight-layout-issue.

    Also, I cannot seem to listen for the orientationchange event itself, so the I tried applying the "scrollTo(0,0)" fix in the resize event instead, but this does not fix things.

    If anyone knows how to get Enyo to listen for the orientationchange event, please let me know.
  • Have you tried enyo.dispatcher.listen(window, 'orientationchange')? That should add it to the normal enyo dispatcher paths so you could handle it via Signals.
  • I did try that, I suspect the orientationchange event is just not always 100% reliable on every platform or something..

    Turns out, the problem I was trying to solve on IOS7 with the on-screen keyboard only happens in the browser. When I run things as a cordova app, things work correctly out-of-the-box.

    My current solution is quite complicated:

    I start out monitoring focusin and focusout events and inspect if the focused element is a textarea or input. If it's an input I also check if the node type is color, email, number, password, search, tel, text or url.

    If these checks are passed, I store a reference to the focused element as a sign that an on-screen keyboard might be showing (false positives apply, haven't encountered false negatives yet).

    Once a resize event is triggered and ios7 is detected, I scroll window.scrollTo(0, 0);, as this seems to help Safari get a little less confused about it's window dimensions.

    Next, if a focused input is stored, I set a flag to remind me a new reflow is required, I blur the focused input, and return true to stop the resize event from waterfalling.

    The blurring of the input will trigger my focusout handler. Inside the focusout handler, I delete the reference to the once focused input and check for a reflow flag. If a reflow flag is present that means the resizeHandler blurred an input.

    If so, I set a 0ms timeout that calls the resized method, to initiate a new reflow in the callback function of the timeout. The 0ms timeout seems to be needed to ensure the reflowing only happens after the IOS device has finished getting rid of the on-screen keyboard.

    When the resizeHandler is triggered there should be no more focused input, and the normal reflow procedure can finally happen.

    It's quite complicated, but if I remove any of these steps, things get messed up. Also if I execute them in cordova, things fail horribly.
Sign In or Register to comment.