I want to know how to handle UI rotation. I have requirement to chang my UI layout when user rotates UI from Potrait to Landscape or vice versa. Let me know which event I need to handle and how do I get device height and width for both kind of rotation and adjust my UI.
I am also interested that if I use various layout then will it be adjusted automatically on UI rotation. Typical case is let say I have created UI using layouts which display two components on main screen, left side one list and right side content of particular item of list (this is same as explorer on windows). In this case if I rotate my UI then will it adjust correctly or I need to handle explicitly.
Please share your inputs on this asap.
Thank you very much in advance for your support.
Regards,
Premal Panchal
.
Marmalade handles Portrait to Landscape and vice-versa movement automatically, so You don't need to code it.
Register for the S3E_SURFACE_SCREENSIZE callback and then you can get notification when the screen size/orientation has changed:
s3eSurfaceRegister( S3E_SURFACE_SCREENSIZE, (s3eCallback)ScreenSizeOrientationChanged );
void ScreenSizeOrientationChanged( s3eSurfaceOrientation *orien, void *pUserData )
{
s3eDebugTracePrintf( "Orientation Changed: width=%d, height=%d, surfacewidth=%d, surfaceheight=%d, blitdirection=%s", orien->m_Width, orien->m_Height, Iw2DGetSurfaceWidth(), Iw2DGetSurfaceHeight(), S3E_SURFACE_BLIT_DIR_ROT180 ? "180" : "0" );
CGame *pGame = (CGame *)pUserData;
if( pGame )
{
pGame->ReCalculateScreenSize( orien->m_Width, orien->m_Height );
}
}
s3eSurfaceUnRegister( S3E_SURFACE_SCREENSIZE, (s3eCallback)ScreenSizeOrientationChanged );
You will notice that the GetSurfaceWidth/Height methods still report the original orientation values, so use the values passsed in the s3eSurfaceOrientation structure
Related
in my app I allow the multitasking mode.
But I need to do some action if my view is too restricted.
Watching Apple documentation I saw this image
You can see that in iPad Pro in SplitView, both views are regular, instead in other iPads both views are compact.
I there something that allow me to know if my current view is regular or compact?
Thanks
This is my solution:
if (self.view.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular){
NSLog(#"REGULAR HORIZONTAL");
return TRUE;
}else{
NSLog(#"COMPACT HORIZONTAL");
return FALSE;
}
If you need to handle it programatically, you can override -traitCollectionDidChange: and look at the self.traitCollection property on that view and make changes depending on the output.
However -viewWillTransitionToSize:withTransitionCoordinator: will get you a more fine grained response to how big the view controller has been resized to.
I'm developing a temporary web app for the iPad. It's really just a stop-gap until a proper mobile solution can be devised for this particular product.
One issue is this app works and looks perfect in Landscape, but in Portrait mode, the dimensions just don't fit.
I'm sure this is a horrible usability crime to even ask such a question, but is there any sort of convention for prohibiting a web app from rotating to Portrait mode?
I'm not looking for an examples of code, I'm just wondering if anything like this exists.
No, there isn't an option. After all html is all about dynamic display of information. Just define the elements of your webapp proper and it will look fine.
You can use the orientation change function to check for the orientation and then show a image or div stating the user that webapp can be opened only in Landscape mode.
window.addEventListener('orientationchange', function(event) {
if (window.orientation == 90 || window.orientation == -90)
{
/* Hiding the Message div */
}
else
{
/* Show a div in Portrait Asking users to switch orientation to Landscape */
}
});
So I have created an App that has a different menu when it is held portrait, but changes when held landscape.
I can get the navigation to work, However I am unsure how to design landscape pages inside Flash?
My stage is set to the standard 640x960 air for iOS, which gives me perfect portrait pages, But when I tilt my phone to landscape the screen obviously changes, and it looks weird. Im hoping someone can tell me how i can get this view inside Flash, while still having the portrait screens too?
I want to have both Portrait and Landscape in the same app, and am currently so confused how I can design this inside flash?
I hope this makes sense, and that someone could throw some help my way!
It's not easy, but you can do it. First, you have to wait until stage is initialized and set it's scaling property to no scale (this will stop resizing page to fill screen). Then you have to listen to stage's resizing (it trigger's every time you rotate iPhone) and to move/scale your display objects in proper way in the listener handler.
addEventListener(Event.ADDED_TO_STAGE, init); //Wait for stage initialization
private function init(e:Event):void { //init handler
removeEventListener(Event.ADDED_TO_STAGE, init); //remove listener, which won't be used more
stage.scaleMode = StageScaleMode.NO_SCALE; //set null scaling and top-left align
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.RESIZE, resize); //add handler for resizing
}
private function resize(e:Event):void { //triggers every time iPhone being rotated
//Move/scale your objects here
}
There is a image control in my page, which support the landscape and portrait layout. I want implement an animation that rotate the image when the oritentaion changed. Which just like the built-in rotate animation of applicationbar. But I have no any idea right now. Could anyone give me a hand?
There are at least two ways to implement it:
1) Catch the OrientationChanged event and animate layout using Fluid UI feature in Expression Blend. It allows you to make smooth transition from one visual state to another.
void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e) {
if(Orientation==PageOrientation.PortraitUp) {
VisualStateManager.GoToState(this, "VisualStatePortrait", true);
}
else {
VisualStateManager.GoToState(this, "VisualStateLandscape", true);
}
}
You should also define visual states for landscape and portrait layout. More on how to declare them you may find out from this video.
2) Another approach introduced by a Windows Phone developer from Microsoft. His solution requires additional code but is more customizible: you can choose between rotation, fade or hybrid animation. A code sample is also included.
Is anyone able to actually make it work properly in Flex SDK 4.6?
Here's a short snippet :
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
addedToStage="onAddedToStage(event)"
title="Title">
<fx:Script>
<![CDATA[
private function onAddedToStage(event:Event):void {
if (stage.autoOrients) {
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging, false, 0, true);
}
}
private function orientationChanging(event:StageOrientationEvent):void {
if (event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN) {
event.preventDefault();
}
}
]]>
</fx:Script>
</s:View>
What I'm trying to achieve is to support Landscape mode in both orientations, so if user turns the device 180 degress, the screen should also rotate. But there should be no action at all, when user rotates the device to one of portrait orientations. Instead, I'm seeing width changes to navigator action bar and sometimes content in portrait orientations, so apparently preventing the event is not enough. I'm using the "official" way Adobe suggests, but the problem is that it's not working very well. Granted, the stage does not change, but it seems that there's something firing in navigator anyway, since you can see the action bar width changing.
I had some success with explicitly setting layoutbounds to fixed width in handler method - this prevents changing the actionbar width, but it's only a temporary solution - if the view is a subject to a transition, or some other redraw - it will again render with bad sizes. As if there was something below that was telling it that it's in portrait mode, even though I'm trying to prevent it.
Before you detonate with some silly ideas like "autoOrient = false", don't. It's clearly not a solution for this problem. Obviously it's a bug with Flex SDK - did anyone find a way to fix it or a stable workaround?
EDIT: apparently others bumped into similar issue:
- http://forums.adobe.com/message/3969531 (the main topic is about something else, but read magic robots's comment)
- http://forums.adobe.com/message/4130972
I'm not sure if this is the right one, did I do something wrong in the end, but after a lot of struggle, I've found this one to be stable solution:
private function onAddedToStage(event:Event):void {
if (stage.autoOrients) {
stage.removeEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging);
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging, false, 100, true);
}
}
private function orientationChanging(event:StageOrientationEvent):void {
event.stopImmediatePropagation();
if (event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN) {
event.preventDefault();
}
}
First thing to note is that addedToStage fires few times (2-3) in mobile application. I don't know why, there's no addChild in my code, obviously. Maybe the AIR runtime does something else. So, to avoid adding unnecessary amount of handlers, the common technique is to remove handler first - it won't do anything, if such handler is not yet registered, but if there is, it will remove it, which will maintain the handler count on 1.
Second thing is the priority of the event - it won't work on 0, it has to be set on something big, to launch before stuff in AIR runtime.
Last thing - event.stopImmediatePropagation() - now, that we're the first to handle the event, we cant prevent this event to be sent further up in this particular scenario.
This together makes the orientation preventing working perfectly - for me the landscape and the reversed landscape (rotated_left, rotated_right) were working and transitioning, while portrait modes did not affect the view at all.
Now, there's danger here - you might want to remove the listener upon leaving the view (on transition animation end, view deactivate or something), because stopImmediatePropagation will prevent the event to be handled in other parts of your application.
I hope Adobe (or Apache now, actually) will take a closer look at this problem and trace my solution.
EDIT
There remaisn a last issue with this solution, which is if application starts while device is in DEFAULT or UPSIDE_DOWN orientation, in this case application will be in portrait mode.
To fix this, a solution is to change Aspect Ratio within addedToStage handler:
if(Stage.supportsOrientationChange) {
stage.setAspectRatio(StageAspectRatio.LANDSCAPE);
}
So I had the same problem you had. I think I finally figured out the solution. Heres what I did:
<s:TabbedViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
...blahblahblah...
width="1024"/>
protected function tabbedviewnavigatorapplication2_applicationCompleteHandler(event:FlexEvent):void {
stage.autoOrients=true;
preventOrient();
}
private function preventOrient():void {
if (stage.autoOrients) {
stage.removeEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging);
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging, false, 100, true);
}
}
private function orientationChanging(event:StageOrientationEvent):void {
if(event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN || event.afterOrientation == StageOrientation.UNKNOWN) {
event.preventDefault();
}
}
Worth noting is that in the application complete handler I set stage.autoOrients to true because in the app.xml file I have it set to false, due to having a splash screen and not wanting users to re-orient the screen during that time. Really the only thing I did different is account for the StageOrientation.UNKNOWN and prevent whatever that would do, set the width to 1024(for the iPad screen, might be different for other tablet devices) in the main mxml file, and removed the stopimmediatepropagation. Hope this helps.