Qt6.4.1 C++ IOS: Disable autorotate programmatically
-
wrote on 17 Dec 2022, 13:42 last edited by
I'm porting a Qt application to IOS(16). This application defines the the allowed orientations from a configuration file. This configuration file (in reality this file consists of many files) defines not only the orientation but also the objects to be drawn and how they should look like. On Android I could implement a small Java file to handle this. But IOS is different. To be able to support all possible orientations I defined in the file
Info.plist
all available orientations. The screen now rotates automatically and I can detect in Qt the actual orientation. I managed to set the orientation programmatically with this small code:void TIOSRotate::rotate(int dir) { float value = 0.0; switch(dir) { case O_LANDSCAPE: value = UIInterfaceOrientationMaskLandscapeRight; break; case O_REVERSE_LANDSCAPE: value = UIInterfaceOrientationMaskLandscapeLeft; break; case O_PORTRAIT: value = UIInterfaceOrientationMaskPortrait; break; case O_REVERSE_PORTRAIT: value = UIInterfaceOrientationMaskPortraitUpsideDown; break; } NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects]; UIWindowScene *scene = (UIWindowScene *)array[0]; UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:value]; [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) { NSLog(@"%@", error); }]; }
I know the possibility to define a view (
UIViewController
) class where I can overwrite some functions to set the allowed orientations. Tried this with a small pure objective-c program and it worked.
I don't know how I should call the delegate and view classes so that it overwrites the function(UIInterfaceOrientationMask)supportedInterfaceOrientations
defined in the view. Can someone point me to an example where I can see how to do this or even better show me some lines of code?I found out that I can get a pointer to the basic view with the following lines:
UIWindow* window = [[UIApplication sharedApplication] keyWindow]; UIViewController *vctrl = [window rootViewController];
Nice, but I don't know if this could help me. And if it helps how?
A.T.
-
I'm porting a Qt application to IOS(16). This application defines the the allowed orientations from a configuration file. This configuration file (in reality this file consists of many files) defines not only the orientation but also the objects to be drawn and how they should look like. On Android I could implement a small Java file to handle this. But IOS is different. To be able to support all possible orientations I defined in the file
Info.plist
all available orientations. The screen now rotates automatically and I can detect in Qt the actual orientation. I managed to set the orientation programmatically with this small code:void TIOSRotate::rotate(int dir) { float value = 0.0; switch(dir) { case O_LANDSCAPE: value = UIInterfaceOrientationMaskLandscapeRight; break; case O_REVERSE_LANDSCAPE: value = UIInterfaceOrientationMaskLandscapeLeft; break; case O_PORTRAIT: value = UIInterfaceOrientationMaskPortrait; break; case O_REVERSE_PORTRAIT: value = UIInterfaceOrientationMaskPortraitUpsideDown; break; } NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects]; UIWindowScene *scene = (UIWindowScene *)array[0]; UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:value]; [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) { NSLog(@"%@", error); }]; }
I know the possibility to define a view (
UIViewController
) class where I can overwrite some functions to set the allowed orientations. Tried this with a small pure objective-c program and it worked.
I don't know how I should call the delegate and view classes so that it overwrites the function(UIInterfaceOrientationMask)supportedInterfaceOrientations
defined in the view. Can someone point me to an example where I can see how to do this or even better show me some lines of code?I found out that I can get a pointer to the basic view with the following lines:
UIWindow* window = [[UIApplication sharedApplication] keyWindow]; UIViewController *vctrl = [window rootViewController];
Nice, but I don't know if this could help me. And if it helps how?
A.T.
wrote on 18 Dec 2022, 13:55 last edited byI tried in the meantime to filter the orientation event like this:
bool MainWindow::eventFilter(QObject *obj, QEvent *event) { Q_UNUSED(obj); if (event->type() == QEvent::OrientationChange) { // do something } return false; }
But this event never occurs. And even if it should occur, I see no way to detect the new orientation. This makes it impossible to filter out the unwanted orientations. I'm still searching for a way to tell Qt to not rotate at all or to rotate only to some particular orientations. Does someone has an idea of how to do this for IOS?
Internally Qt has a platform specific method to handle rotation. The only thing I'm missing is a way do define the allowed orientations. Until now I found no way to do this. Nor by looking at the source of Qt nor by adding some Objective-C code.
I tried to define a newUIViewController
containing all the necessary functions and tried to inject it into the main container view. But this doesn't work.@interface TIOSViewController : UIViewController @property (nonatomic, assign) BOOL blockRotation; @end @implementation TIOSViewController - (void)viewDidLoad { [super viewDidLoad]; self.blockRotation = YES; } - (BOOL)shouldAutorotate { return self.blockRotation; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { if (TIOSRotate::getAllowedOrientation()) return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; else return UIInterfaceOrientationMaskLandscape; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { if (TIOSRotate::getAllowedOrientation()) return UIInterfaceOrientationPortrait; else return UIInterfaceOrientationLandscapeLeft; } - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { if (self.blockRotation) { if (TIOSRotate::getAllowedOrientation()) return UIInterfaceOrientationMaskPortrait; else return UIInterfaceOrientationMaskLandscape; } return UIInterfaceOrientationMaskAll; } - (void)allowRotation:(BOOL)allow { self.blockRotation = allow; } @end TIOSViewController *View = nil;
In another class I have:
if (!View) View = [TIOSViewController alloc]; if (View) { [View allowRotation:NO]; NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects]; UIWindowScene *scene = (UIWindowScene *)array[0]; UIWindow* window = [scene keyWindow]; UIViewController *vctrl = [window rootViewController]; [View willMoveToParentViewController:vctrl]; BOOL first = [View becomeFirstResponder]; if (!first) { MSG_WARNING("New View is not the first responder!"); }
Unfortunately the above code doesn't work and I run out of ideas. I would appreciate some help here.
A.T.
1/2