With Cordova 5.1.1, when executing "cordova build ios", any device orientation settings previously selected in the XCode project are deleted leaving the orientation settings checkboxes unselected.
While the "orientation" config preference may provide a means of forcing orientation, I need to be able to set different orientation preferences for the iPad and iPhone.
All previous Cordova versions (below 5) respected those settings. Any ideas?
Using XCode 6.3.2.
EDIT:
According to @Abhinav Gujjar the issue causing cordova prepare
to overwrite manual changes made to orientation settings in the .plist has been fixed. However, AFAIK there's still no way to set different orientation preferences for iPad vs iPhone in the config.xml, so the answer below stands.
UPDATE:
I created the plugin cordova-custom-config, which wraps up the hook below and means platform-specific custom config blocks (such as these orientation settings) can be defined in config.xml. So you can use the plugin rather than need to manually create the hook below.
This was introduced in the Cordova 5.0.0 CLI - see here.
In the meantime, I've been using an after_prepare hook as a workaround. Just place the following in <your_project>/hooks/after_prepare/some_file.js
and change the orientation settings as appropriate:
#!/usr/bin/env node
// Set support for all orienations in iOS .plist - workaround for this cordova bug: https://issues.apache.org/jira/browse/CB-8953
var platforms = process.env.CORDOVA_PLATFORMS.split(',');
platforms.forEach(function(p) {
if (p == "ios") {
var fs = require('fs'),
plist = require('plist'),
xmlParser = new require('xml2js').Parser(),
plistPath = '',
configPath = 'config.xml';
// Construct plist path.
if (fs.existsSync(configPath)) {
var configContent = fs.readFileSync(configPath);
// Callback is synchronous.
xmlParser.parseString(configContent, function (err, result) {
var name = result.widget.name;
plistPath = 'platforms/ios/' + name + '/' + name + '-Info.plist';
});
}
// Change plist and write.
if (fs.existsSync(plistPath)) {
var pl = plist.parseFileSync(plistPath);
configure(pl);
fs.writeFileSync(plistPath, plist.build(pl).toString());
}
process.exit();
}
});
function configure(plist) {
var iPhoneOrientations = [
'UIInterfaceOrientationLandscapeLeft',
'UIInterfaceOrientationLandscapeRight',
'UIInterfaceOrientationPortrait',
'UIInterfaceOrientationPortraitUpsideDown'
];
var iPadOrientations = [
'UIInterfaceOrientationLandscapeLeft',
'UIInterfaceOrientationLandscapeRight',
'UIInterfaceOrientationPortrait',
'UIInterfaceOrientationPortraitUpsideDown'
];
plist["UISupportedInterfaceOrientations"] = iPhoneOrientations;
plist["UISupportedInterfaceOrientations~ipad"] = iPadOrientations;
}
Note: you'll need to install the plist and xml2js node modules if you don't already have them.
IF you want to, you can to it programmatically on the JS side.
For iOS, orientation can be programmatically controlled by defining a javascript callback on window
/**
// @param {Number} degree - UIInterfaceOrientationPortrait: 0,
// UIInterfaceOrientationLandscapeRight: 90,
// UIInterfaceOrientationLandscapeLeft: -90,
// UIInterfaceOrientationPortraitUpsideDown: 180
* @returns {Boolean} Indicating if rotation should be allowed.
*/
function shouldRotateToOrientation(degrees) {
return true;
}
Set allowed orientations in your config.xml
file
<platform name="ios">
<preference name="Orientation" value="all" />
</platform>
And add the shouldRotateToOrientation(degrees)
onDeviceReady: function() {
app.receivedEvent('deviceready');
window.shouldRotateToOrientation = function(degrees) {
//if device an iPad ?
if ( navigator.userAgent.match(/iPad/i) ) {
return true;
}
//else if device an iPhone ?
else if (navigator.userAgent.match(/iPhone/i)) {
if (degrees == 0) { //orientation is portrait
return true;
}
return false; //refuse all other orientations for iPhone
}
return true;
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With