In my cocos2d application, inside the applicationDidFinishLaunching method for my app delegate, I set the orientation via [director setDeviceOrientation:kCCDeviceOrientationPortrait] because I really only want portrait. However, Apple rejected my app saying it must support upside down portrait as well.
I'm not certain how I detect this, though. Reading the currentDevice orientation seems to return an unknown orientation, so my questions are twofold:
1) How am I supposed to detect the orientation so I can properly set it to either portrait or upsidedown portrait (where it will stay for good).
2) I suspect I'll have an issue with the splash screen because it's loaded before I reach this point in the delegate. How can I properly detect the orientation so I can set the right splash screen?
I can only edit the codes to fix your first question.. i hope you are using .99.5..
in RootViewController.h, in the function
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
look for this line:
#elif GAME_AUTOROTATION == kGameAutorotationUIViewController
{
return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );
}
change to
return ( UIInterfaceOrientationIsPortrait( interfaceOrientation ) );
Related
I have a Qt / QML application on iOS. It is coded in C++ but I can include objective-c code in it.
I can change programmatically the orientation of the screen, which changes the orientation of the application, without changing the orienation of the iPad, and the user has to turn it when he notices the change of orientation of the screen.
I do that as I need to force the orientation depending on what I display on the application.
What I need to do now is to lock the automatic change of orientation (due to physical change) as I need it to be landscape sometimes and portrait other times.
To change the orientation programmatically, I found the above solution which works:
in my plist file, orientations must be allowed:
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
in my C++ code where I can insert objective-c:
void setScreenOrientation(bool inIsPortrait)
{
if(#available(iOS 16, *))
{
NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
UIWindowScene *scene = (UIWindowScene *)array[0];
UIInterfaceOrientationMask newOrientation;
if(inIsPortrait)
newOrientation = UIInterfaceOrientationMaskPortrait;
else
newOrientation = UIInterfaceOrientationMaskLandscapeRight;
UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:newOrientation];
[scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) { }];
}
else
{
//does not work on iOS 16, outputs following error:
//[Orientation] BUG IN CLIENT OF UIKIT: Setting UIDevice.orientation is not supported. Please use UIWindowScene.requestGeometryUpdate(_:)
NSNumber *newOrientation;
if(inIsPortrait)
newOrientation = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
else
newOrientation = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:newOrientation forKey:#"orientation"];
}
}
}
So with that, when I want to change the orientation from portrait to landscape or vice versa, I just call the function with the correct parameter.
The problem is that when I physically turn the iPad, the screen automatically changes its orientation due to the plist file. So when I force to landscape, the user sees the change so turns its iPad, but if he turns back to portrait, the automatic change will put back the screen to portrait, without calling my function of course.
I can't remove the orientations from the plist file as they are required if I want to change it programmatically.
But I would like to lock the screen in the selected orientation at the end of the function, and of course, unlock it at the beginning, so that physically turn the iPad won't change the screen orientation.
I found solutions with the function "shouldAutorotate" but it has to be overwritten and called in viewDidLoad or supportedInterfaceOrientationsForWindow which are specific to an objective-c implementation and architecture.
I found : Lock orientation with native Objective-C code from Qt
but I can't do that in my code as I don't have any ViewController, ... it's a Qt / QML application.
I would like to have something that I can call in my function, something to change the supported orientations, so modify "supportedInterfaceOrientationsForWindow" by calling it directly in a function. Something like:
[[UIApplication ???] supportedInterfaceOrientationsForWindow] = UIInterfaceOrientationMaskPortrait; //or UIInterfaceOrientationMaskLandscapeRight depending on what I need
or any other instructions but without having to override supportedInterfaceOrientationsForWindow.
Thanks
I'm creating a iOS video camera app using Qt5.4.
For this I need to determine the current orientation of the device to rotate the video in the VideoOutput element.
As we can see there's a autoOrientation property but it doesn't work as I expect: if I keep switching the orientation it starts to have a weird behaviour i.e. setting the wrong orientation.
Then I tried to apply the rotation based on the Screen.primaryOrientation property:
Copying the function defined in this example, I've a created a similar version, which you can find here.
I call it every time width or height changes, like this:
onWidthChanged: { video.orientation = changeOrientation(); }
onHeightChanged: { video.orientation = changeOrientation(); }
However, it seems that the Inverted orientations are completely ignored, which is strange since they are listed in the documentation.
Anyone has any idea about why it's happening?
UPDATE:
I could isolate the problem when using autoOrientation, basically there's a menu on top of the VideoOutput, the menu is a RowLayout, it's visible only if the user clicks on the menu icon, and only if the user clicks on the menu icon the orientation gets messy.
However, in any situation the InvertedPortrait is not recognized.
The app is set up for only landscape.
In Project->target->Summary->Supported Interface Orientations, I enabled the 2 landscape icons (both left and right).
And in AppDelegate.m, the below code is written:
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
When the app is running on the device, the view showed at the beginning after the default cocos2d icon, all the positions are wrong which were all moved to the right-down side. When I rotate the screen, everything goes right, all in right position.
What's wrong?
I also tried the method below:
I disable all the icons in In Project->target->Summary->Supported Interface Orientations.
The code in AppDelegate still in use.
Then the view at the very beginning is ok but the screen can be rotated to protrait.
....
Any one can help?
Also put these two for iOS6 orientation, in AppDelegate.
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
{
return UIInterfaceOrientationMaskLandscape;
}
Look at this question and answer once.
before to update my cocos2d 1.0.1 to 2.0rc1 in my app, I was calling [[CCDirector sharedDirector] setDeviceOrientation:(ccDeviceOrientation)currentOrientation]; into some scenes when detected one change on orientation and then load other scene in portrait or lanscape depending the currentOrientation.
But now I don't have any idea about how I can do it.
Orientation setOrientation ( Orientation orientation )
Callback by CCDirector for change device orientation.
The defination of orientation which CCDirector want change to.
Returns
The actual orientation of the application.
Open AppDelegate.m and locate this method:
// Supported orientations: Landscape. Customize it for your own needs
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
Return YES for all the orientations your app supports.
I want to set the contentsize of scrollayer.
I have a scrollayer, it's CCLayer type and moving is set by ccTouchMove. I have one schedule for smoothing. BUT.
Problem is that scrolling layer is big like the whole display. I want to set the contentsize of scrollayer. Content in this layer will be scroll and showing ONLY in this layer. Not taking up the whole display. Something like this
Scrolling just in gray CCLayer (scrollayer) ....NOT WHOLE SCREEN.
Can you help me?
P.S.: Setting CCLayerColor and initWithColor:Width:Height: is not working. It just makes some stupid color box and it's moving too.
ok, honestly i would put the window frame at a higher z than the scrolling object ... if you dont you may have to crop and change sprite on the fly for the window content, nasty (at least that is the one way i could do this, without further research).
so :
// initialize this logic somewhere useful
CCNode scrollableContent;
CCSprite windowFrame;
BOOL isScrollPossible;
[self addChild:scrollableContent z:0];
[self addChild:windowFrame z:1];
// and in the touch delegate methods
-(void) ccTouchBegan:{
check if the touch happened in the window, if yes, scrolling is possible
}
-(void) ccTouchMoved:{
if (isScrollPossible) {
compute displacement
compute nextPosition for scrollableContent node;
if ( nextPosition in window ) {
// make scrollableContent follow touch
scrollableContent.position=nextPosition;
} else {
// stop any further scrolling until the next 'touch began'
isScrollPossible=NO;
}
} else {
// scroll not possible, do nothing
}
}
This is the basic idea. You may need clamping logic to prevent the creeping of scrollableContent beyond the edges of the window.
Edited for typos.
After trying desperately with masking and GL_SCISSOR, I settled on cutting a hole in the foreground and only moving the background object when onTouchMoved updated.
To see it in action, have a look at the Stats page of Angry Gran.