cordova-plugin-screen-orientation icon indicating copy to clipboard operation
cordova-plugin-screen-orientation copied to clipboard

Screen doesn't rotate many times on iOS from landscape to portrait

Open sagrawal31 opened this issue 5 years ago • 6 comments

On iOS (mostly on iPhone7 & iPhoneX), when we switch from landscape to portrait, the orientation doesn't change. There are two behaviour that we noticed:

  1. The orientation doesn't change at all
  2. Only the orientation of the webview doesn't change but keyboard opens fine in expected orientation

Example of behaviour2 (buggy) when navigating to this page from a landscape page: behaviour2-buggy

While this should be the page: behaviour2-correct

The same happens with the behaviour 1.

We tried to identify the pattern but nothing helped. We also tried to add a delay in between changing the orientation and navigation between the page but the behaviour is same.

Ionic:

   ionic (Ionic CLI)  : 4.8.0 (/usr/local/lib/node_modules/ionic)
   Ionic Framework    : ionic-angular 3.9.2
   @ionic/app-scripts : 3.2.0

Cordova:

   cordova (Cordova CLI) : 7.1.0
   Cordova Platforms     : android 7.1.2, ios 4.5.5
   Cordova Plugins       : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 1.2.1, (and 21 other plugins)

System:

   Android SDK Tools : 26.1.1 (/Users/shashank/Library/Android/sdk)
   ios-deploy        : 1.9.2
   ios-sim           : 5.0.11
   NodeJS            : v8.12.0 (/usr/local/bin/node)
   npm               : 6.4.1
   OS                : macOS Mojave
   Xcode             : Now using system ruby. Xcode 10.1 Build version 10B61

sagrawal31 avatar Jan 17 '19 19:01 sagrawal31

+1

ankit18singh avatar Feb 06 '19 09:02 ankit18singh

This bug can be reproduced in a simple test case:

  • Create a test project that contains this plugin
    • Ensure all orientations are allowed in the plist configuration
  • Set orientation.lock('portrait') on deviceready
  • Build and run on a device/simulator that is already in landscape orientation (before the app launches)
  • Observe the webview (and splashscreen if present) are presented in landscape orientation initially
  • If an input exists in the upper half of the screen, observe that selecting it presents the keyboard in portrait
  • Rotate the device/simulator back to portrait
  • Observe the app interface rotates to portrait
  • Observe the low half of the webview does not respond to touch events

I'm thinking this solution may require changes to both this plugin and cordova-ios: While a reference can be obtained to the CDVViewController via the global AppDelegate from CDVOrientation class, I'm not sure the public properties/functions exposed by the ViewController are currently sufficient to resolve this issue.

dpa99c avatar Mar 12 '19 19:03 dpa99c

That's amazing @dpa99c

sagrawal31 avatar Mar 12 '19 20:03 sagrawal31

I use a somehow hackish but working workaround in one of my projects. It consists of two parts. The first is a fork of this repo with adjusted code for iOS. The second is a little script being invoked during build as cordova hook. It has a bit of "works for me" character. With this being said, here it is:

The plugin: https://github.com/codevise/cordova-plugin-screen-orientation

And the hook-script:

/*global require, module, __dirname, console*/

var insertAfter = require('./utils/insertAfter');

var mainViewController = __dirname + '/../platforms/ios/<your-project-name>/Classes/MainViewController.m';
var headMarker = "#import \"MainViewController.h\"\n";
var bodyMarker = "#pragma mark View lifecycle\n";

module.exports = function(context) {
  console.log('Overriding supported orientations...');

  insertAfter(mainViewController,
              headMarker,
              "#import \"CDVOrientation.h\"\n"
  );

  insertAfter(mainViewController,
              bodyMarker,
              "\n- (NSUInteger) supportedInterfaceOrientations\n" +
              "{\n" +
              "    return (unsigned long)[CDVOrientation allowedOrientations];\n" +
              "}\n"
  );
};

Don't forget to adjust the path for the MainViewController to match your project structure and save it to scripts/override_supported_orientations_for_ios.js within your cordova project.

The required insertAfter.js goes to scripts/utils:

/*global require, module*/

var fs = require('fs');

module.exports = function insertAfter(filename, after, text) {
  var data = fs.readFileSync(filename, 'utf8');

  if (data.indexOf(text) < 0) {
    data = data.replace(new RegExp(after, 'g'), after + text);
  }

  fs.writeFileSync(filename, data, 'utf8');
};

Then add the script as hook in the config.xml:

<platform name="ios">
  <hook src="scripts/override_supported_orientations_for_ios.js" type="after_prepare" />
...

Again, this doesn't claim to be a solution, just a way to "get it done".

schoetty avatar Jun 18 '19 12:06 schoetty

@sagrawal31 - Can You just try installing plugin from here . https://github.com/Anuj-logiciel/cordova-plugin-screen-orientation

Anuj-logiciel avatar Jul 30 '19 18:07 Anuj-logiciel

Any news on this issue? It still happens in our app.

  • cordova 9.0.0
  • cordova-ios 5.1.1
  • cordova-plugin-screen-orientation 3.0.2

ucsbricks avatar Mar 17 '20 10:03 ucsbricks