Resolves iOS rotation issue via timeout, due to event timing issues.

This commit is contained in:
Joshua A. Horton 2018-04-27 13:36:06 +07:00
parent b68d63fe68
commit 73e2bd4ced
2 changed files with 38 additions and 57 deletions

View file

@ -469,67 +469,43 @@ if(!window['keyman']['initialized']) {
/**
* Use rotation events to adjust OSK and input element positions and scaling as necessary
*/
keymanweb.handleRotationEvents=function()
{
if(device.OS == 'iOS')
util.attachDOMEvent(window,'orientationchange',keymanweb.rotateDevice);
// Also manage viewport rescaling after rotation on Android
if(device.OS == 'Android')
{
osk.wasVisible=osk.isVisible;
// Hide OSK at start of rotation
if('onmozorientationchange' in screen)
util.attachDOMEvent(screen,'mozorientationchange',osk.hideNow);
else if(util.device.OS != "iOS")
util.attachDOMEvent(window,'orientationchange',osk.hideNow);
keymanweb.handleRotationEvents=function() {
// General handler for rotation events.
var rotationHandler: () => void = function() {
osk.wasVisible = osk.isVisible();
osk.hideNow();
// Then align inputs and redisplay the OSK on resize event following rotation
var rotationHandler: () => void = function() {
// At least on simulators, it seems we can reach a minor race condition on screen-size updates without a timeout.
window.setTimeout(function() {
keymanweb.alignInputs(true);
osk.hideLanguageList();
osk._Load();
if(osk.wasVisible) {
osk._Show();
}
};
}, 500);
};
if(device.OS == 'iOS') {
util.attachDOMEvent(window, 'orientationchange', rotationHandler);
}
// Also manage viewport rescaling after rotation on Android
if(device.OS == 'Android') {
//osk.wasVisible=osk.isVisible;
// Hide OSK at start of rotation
if('onmozorientationchange' in screen)
util.attachDOMEvent(screen,'mozorientationchange',osk.hideNow);
// Then align inputs and redisplay the OSK on resize event following rotation
util.attachDOMEvent(window, 'resize', rotationHandler);
if(util.device.OS == "iOS") {
util.attachDOMEvent(window, 'orientationchange', rotationHandler);
}
}
//TODO: may be able to recognize start of rotation using accelerometer call...
//util.attachDOMEvent(window,'devicemotion',keymanweb.testRotation);
}
/**
* Hide the URL bar and resize the OSK after rotation (device dependent)
*
* @param {Event} e event (not used directly)
*
*/
keymanweb.rotateDevice = function(e) // Rewritten for I3363 (Build 301)
{
osk.hideLanguageList();
if(!osk._Visible) return;
// Always re-adjust OSK rows for rounding to nearest pixel
// if(osk.ready)
// {
//nLayer=osk.resetRowLengths(); // clear aligned flag for all layers
//osk.adjustRowLengths(nLayer); // adjust lengths in visible layer
// }
osk.adjustHeights();
// Hide the URL bar on Android phones - offset is zero for iPhone, but should not be applied here
if(device.formFactor == 'phone' && device.OS == 'Android')
window.setTimeout(function(){window.scrollTo(0,1);},1000);
}
/**
* Possible way to detect the start of a rotation and hide the OSK before it is adjusted in size
*

View file

@ -2022,7 +2022,9 @@ if(!window['keyman']['initialized']) {
}
// Correct for viewport scaling (iOS - Android 4.2 does not want this, at least on Galaxy Tab 3))
if(device.OS == 'iOS') height=height/util.getViewportScale();
if(device.OS == 'iOS') {
height=height/util.getViewportScale();
}
// Correct for devicePixelratio - needed on Android 4.1.2 phones,
// for Opera, Chrome and Firefox, but not for native browser! Exclude native browser for Build 344.
@ -2040,25 +2042,28 @@ if(!window['keyman']['initialized']) {
*
* @return {number} height in pixels
**/
osk.getWidth=function()
{
osk.getWidth=function() {
// KeymanTouch - get OSK height from device
if(typeof(keymanweb['getOskWidth']) == 'function') return keymanweb['getOskWidth']();
if(typeof(keymanweb['getOskWidth']) == 'function') {
return keymanweb['getOskWidth']();
}
// screen width always correct for iOS (iOS 8, anyway)
var width=screen.width;
// On Android (Opera, Chrome and Firefox; native browser not supported)
// must use document client width, using window width only if document undefined
if(device.OS == 'Android')
{
var width: number;
if(util.device.OS == "iOS") {
// iOS does not interchange these values when the orientation changes!
//width = util.portraitView() ? screen.width : screen.height;
width = window.innerWidth;
} else if(device.OS == 'Android') {
try {
width=document.documentElement.clientWidth;
}
catch(ex) {
width=screen.availWidth;
}
} else {
width=screen.width;
}
return width;
}