[iOS] Can't get hardware orientation on startup


#1

Hi, I’m trying to detect the device orientation when the app is launched.

But it seems like the app always changes its orientation to OF_ORIENTATION_DEFAULT on startup regardless of its current hardware orientation.

For example, if I start an app in a landscape mode, it always changes to a default portrait mode.

Here’s my example code,

in main.mm

int main() {
    
    //  here are the most commonly used iOS window settings.
    //------------------------------------------------------
    ofiOSWindowSettings settings;
    settings.enableRetina = true; // enables retina resolution if the device supports it.
    settings.enableDepth = true; // enables depth buffer for 3d drawing.
    settings.enableAntiAliasing = true; // enables anti-aliasing which smooths out graphics on the screen.
    settings.numOfAntiAliasingSamples = 4; // number of samples used for anti-aliasing.
    settings.enableHardwareOrientation = true; // enables native view orientation.
    settings.enableHardwareOrientationAnimation = false; // enables native orientation changes to be animated.
    settings.glesVersion = OFXIOS_RENDERER_ES1; // type of renderer to use, ES1, ES2, etc.
    
    ofCreateWindow(settings);
    
	return ofRunApp(new ofApp);
}

in ofApp.mm

//--------------------------------------------------------------
void ofApp::setup(){	

    switch (ofGetOrientation()) {
            
        case OF_ORIENTATION_DEFAULT:
            cout << "OF_ORIENTATION_DEFAULT" << endl;
            break;
        case OF_ORIENTATION_180:
            cout << "OF_ORIENTATION_180" << endl;
            break;
        case OF_ORIENTATION_90_LEFT:
            cout << "OF_ORIENTATION_90_LEFT" << endl;
            break;
        case OF_ORIENTATION_90_RIGHT:
            cout << "OF_ORIENTATION_90_RIGHT" << endl;
            break;
        case OF_ORIENTATION_UNKNOWN:
            cout << "OF_ORIENTATION_UNKNOWN" << endl;
            break;
        default:
            break;
    }
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
	
    ofSetBackgroundColor(0);
    ofDrawBitmapString("TOP LEFT CORNER", 50, 50);
}

And it always prints OF_ORIENTATION_DEFAULT regardless of the device orientation.
I think this is a bug since this worked properly on of_v0.9.0_ios version. ( I had to change some codes though as there were some bugs Fixed orientation issues on iOS8)

If anyone has a solution to this, please let me know.
I tested this on both of_v0.9.8_ios and the latest nightly build.

Thanks!


#2

I opened an issue on gitHub

https://github.com/openframeworks/openFrameworks/issues/5612


#3

Hi @cuinjune,

I am able to get the orientation right on startup using 0.9.8. I configure the app as an “native” app. Here is how I set up my main.mm:
int main() {

    //  here are the most commonly used iOS window settings.
    //------------------------------------------------------
    ofiOSWindowSettings settings;
    settings.enableRetina = false; // enables retina resolution if the device supports it.
    settings.enableDepth = false; // enables depth buffer for 3d drawing.
    settings.enableAntiAliasing = false; // enables anti-aliasing which smooths out graphics on the screen.
    settings.numOfAntiAliasingSamples = 0; // number of samples used for anti-aliasing.
    settings.enableHardwareOrientation = true; // enables native view orientation.
    settings.enableHardwareOrientationAnimation = true; // enables native orientation changes to be animated.
    settings.glesVersion = OFXIOS_RENDERER_ES2; // type of renderer to use, ES1, ES2, etc.
    settings.enableRetina = true;

    ofAppiOSWindow * window = (ofAppiOSWindow *)(ofCreateWindow(settings).get());
    window->startAppWithDelegate("iOSAppDelegate");

    return 0;
}

For more info about setting it as a native app, you can check out the Examples->ios->iosNativeExample

Also, did you configure “Supported interface orientations” in your info.plist? In my case, I only support landscape mode, and I have to specify this there to get the Launchscreen working correctly.

If you are like me, you should overwrite this function in your custom ofxiOSViewController:

  • (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
    }

#4

hi @Thinium
Thanks for your suggestion.

Did you get the orientation on startup using ofGetOrientation or using objective-C?
Can you share your project if you have an empty one? I would appreciate it.

UPDATE : I don’t think I will need it as I found out the way to fix this. Thank you anyway :slight_smile:


#5

I figured out what was causing it and how to fix it.

- The Problem
It seems like ofiOSWindowSettings::setupOrientation was added in ofAppiOSWindow.h at some point since OF 0.9.x. (It didn’t exist in 0.9.0)
ofiOSWindowSettings::setupOrientation allows one to set the desired orientation on startup.

For example in main.mm, if you add
settings.setupOrientation = OF_ORIENTATION_90_LEFT;
It will make the app always start in a landscape orientation.

And since the default setting of ofiOSWindowSettings::setupOrientation is currently set to OF_ORIENTATION_DEFAULT, the app always starts in portrait mode regardless of the device orientation before launching the app.

This can be problematic if you want to create apps that support multiple orientations and it can cause a bad user experience since users should rotate the device on startup unnecessarily.

- The Solution
My solution is to make use of OF_ORIENTATION_UNKNOWN which currently does nothing but just changes to OF_ORIENTATION_DEFAULT on startup.
So if ofiOSWindowSettings::setupOrientation is set to OF_ORIENTATION_UNKNOWN, the app will no longer always start in OF_ORIENTATION_DEFAULT orientation but it will follow the device’s current orientation on startup.

To achieve this, there are 3 parts to be fixed.

Firstly, in ofAppiOSWindow.h,
in line 49, replace this
setupOrientation = OF_ORIENTATION_DEFAULT;
with this below
setupOrientation = OF_ORIENTATION_UNKNOWN;

Secondly, in ofAppiOSWindow.mm,
inside void ofAppiOSWindow::setup() {}, find and uncomment below.

//  if(settings.setupOrientation == OF_ORIENTATION_UNKNOWN) {
//       settings.setupOrientation = OF_ORIENTATION_DEFAULT;
//  }

And lastly, in ofxiOSAppDelegate.mm,

inside - (void)applicationDidFinishLaunching:(UIApplication *)application {}, find
ofOrientation defaultOrient = ofGetOrientation();
And add this right below it

if (defaultOrient == OF_ORIENTATION_UNKNOWN) {
		
	if(bDoesHWOrientation) {
		// update the window orientation based on the orientation of the device //
		switch (iOrient) {
			case UIInterfaceOrientationPortrait:
				defaultOrient = OF_ORIENTATION_DEFAULT;
				break;
			case UIInterfaceOrientationPortraitUpsideDown:
				defaultOrient = OF_ORIENTATION_180;
				break;
			case UIInterfaceOrientationLandscapeLeft:
				defaultOrient = OF_ORIENTATION_90_RIGHT;
				break;
			case UIInterfaceOrientationLandscapeRight:
				defaultOrient = OF_ORIENTATION_90_LEFT;
				break;
		}
	} else {
		defaultOrient = OF_ORIENTATION_DEFAULT;
	}
	ofSetOrientation(defaultOrient);
}

And now if you want to test it,
in main.mm, make sure you enable hardware orientation as below.
settings.enableHardwareOrientation = true;

And in ofApp.mm, add this in setup() {} so you can print the orientation on startup

switch (ofGetOrientation()) {
        
    case OF_ORIENTATION_DEFAULT:
        cout << "OF_ORIENTATION_DEFAULT" << endl;
        break;
    case OF_ORIENTATION_180:
        cout << "OF_ORIENTATION_180" << endl;
        break;
    case OF_ORIENTATION_90_LEFT:
        cout << "OF_ORIENTATION_90_LEFT" << endl;
        break;
    case OF_ORIENTATION_90_RIGHT:
        cout << "OF_ORIENTATION_90_RIGHT" << endl;
        break;
    case OF_ORIENTATION_UNKNOWN:
        cout << "OF_ORIENTATION_UNKNOWN" << endl;
        break;
    default:
        break;
}

Now, if you run the app, it will always follow the current device’s orientation on startup unless you manually set ofiOSWindowSettings::setupOrientation in main.mm

I tested this on both OF v0.9.8 and the latest nightly builds.
I also tested this on both simulator and real device(iPad Air 2)

I would appreciate if someone can confirm this fix so it can be updated in OF.

https://github.com/openframeworks/openFrameworks/issues/5612


#6

Hi! Sorry my previous reply was not correct. I actually re-adjusted the device orientation during start-up (so a hacky-quick fix). But then I ran into the issue that the app isn’t shown correctly as a screenshot. I tried your solution and it fixed the issue. I would vote for getting this into the next ios version of OF :slight_smile: