Cordova 5 构建命令正在删除 iOS 设备方向设置

Cordova 5 build command is deleting iOS device orientation settings

对于 Cordova 5.1.1,当执行 "cordova build ios" 时,之前在 XCode 项目中选择的任何设备方向设置都将被删除,方向设置复选框未选中。

虽然 "orientation" 配置首选项可以提供一种强制方向的方法,但我需要能够为 iPad 和 iPhone 设置不同的方向首选项。

所有以前的 Cordova 版本(低于 5)都遵循这些设置。有什么想法吗?

使用 XCode 6.3.2.

编辑:

根据 @Abhinav Gujjar,导致 cordova prepare 覆盖对 .plist 中的方向设置所做的手动更改的问题已得到解决。但是,AFAIK 仍然无法在 config.xml 中为 iPad 与 iPhone 设置不同的方向偏好,因此下面的答案是正确的。

更新:

我创建了插件 cordova-custom-config,它包含了下面的钩子,这意味着可以在 config.xml 中定义特定于平台的自定义配置块(例如这些方向设置)。所以你可以使用插件而不需要手动创建下面的钩子。


这是在 Cordova 5.0.0 CLI 中引入的 - see here

与此同时,我一直在使用 after_prepare 挂钩作为解决方法。只需将以下内容放入 <your_project>/hooks/after_prepare/some_file.js 并适当更改方向设置:

#!/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;
}

注意:如果您还没有 plist 和 xml2js 节点模块,则需要安装它们。

如果您愿意,可以在 JS 端以编程方式进行。

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;
}

在您的 config.xml 文件中设置允许的方向

<platform name="ios">
    <preference name="Orientation" value="all" />
</platform>

并添加 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;
    };
}

此问题已解决,您现在可以在 config.xml

中将方向指定为 'all'
<platform name="ios">
      <preference name="Orientation" value="all" />
</platform>

Docs