xamarinios8playn

How to rescale a PlayN application with iOS 8 SDK?


The context of this question is iOS 8, Xamarin and PlayN with an application in landscape mode only.

I used to rescale my application in FinishedLaunching based on UIScreen.MainScreen.Bounds to adapt to different screen sizes.With the iOS 8 SDK, the semantics of the API changed. Previously, UIScreen was not orientation dependent. Here the code for previous SDK that used to work fine:

public partial class AppDelegate : UIApplicationDelegate
{
    public override bool FinishedLaunching (UIApplication app, NSDictionary options)
    {
        app.SetStatusBarStyle (UIStatusBarStyle.LightContent, false);

        IOSPlatform.Config config = new IOSPlatform.Config ();
        config.orients = IOSPlatform.SupportedOrients.LANDSCAPES;
        IOSPlatform.register (app, config);

        System.Drawing.RectangleF bounds = UIScreen.MainScreen.Bounds;

        // Flip width and height when in landscape for iOS SDK before iOS 8
        float screenHeight = bounds.Width; 
        float screenWidth  = bounds.Height;

        float heightRatio = screenHeight / MyGame.HEIGHT;
        float widthRatio  = screenWidth / MyGame.WIDTH;

        float ratio = (heightRatio < widthRatio ? heightRatio : widthRatio);
        PlayN.graphics ().rootLayer ().setScale (ratio, ratio);
        MyGame game = new MyGame ();
        PlayN.run (game);
        return true;
    }
}

With iOS 8 SDK, UIScreen is now interface oriented. I thought just removing the code flipping height and width above would be sufficient to migrate. But this is not the case. The UI is moved to the right by approximatively one third of the screen and is distorted.

Context :

Any advice to migrate this code would be appreciated.


Solution

  • The solution is to migrate to PlayN 1.9 alpha 1 which is now based on RoboVM instead of Xamarin.

    In Info.plist.xml:

    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationLandscapeLeft</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationLandscapeLeft</string>
    </array>
    

    and the java code launching the game (no need for C# anymore)

    public class MetroRoboVM extends UIApplicationDelegateAdapter {
    
      @Override
      public boolean didFinishLaunching (UIApplication app, UIApplicationLaunchOptions launchOpts) {
        app.setStatusBarStyle (UIStatusBarStyle.LightContent, false);
    
        RoboPlatform.Config config = new RoboPlatform.Config ();
        config.orients = UIInterfaceOrientationMask.LandscapeLeft; 
        RoboPlatform platform = RoboPlatform.register(app, config);
        addStrongRef(platform);
    
        String systemVersion = UIDevice.getCurrentDevice().getSystemVersion();
        int indexPoint = systemVersion.indexOf(".");
        if (indexPoint > 0) {
          systemVersion = systemVersion.substring(0,indexPoint);
        }
        int majorVersionNumber = Integer.parseInt(systemVersion);
        boolean isIOS8 = majorVersionNumber >= 8;
        CGSize bounds = UIScreen.getMainScreen().getBounds().size();
    
        double screenHeight = isIOS8 ? bounds.height() : bounds.width(); 
        double screenWidth  = isIOS8 ? bounds.width()  : bounds.height();
    
        double heightRatio = screenHeight / MyGame.HEIGHT;
        double widthRatio =  screenWidth / MyGame.WIDTH;
        double ratio = (heightRatio < widthRatio ? heightRatio : widthRatio);
        PlayN.graphics().rootLayer().setScale ((float)ratio, (float)ratio);
    
        platform.run(new MyGame());
        return true;
     }
    ...
    }