StageOrientationEvent.ORIENTATION_CHANGING not dispatched - ios

I'm testing my starling application on iPhone 4, I suspect this is happening because of the obsolete IOS version.
package
{
import flash.events.Event;
import flash.events.StageOrientationEvent;
import flash.display.Sprite;
public class Startup extends Sprite
{
public function Startup():void
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChangeListener);
}
private function orientationChangeListener(e:StageOrientationEvent):void
{
Debug.write("orientation: " + stage.orientation); //Never called
}
}
}
application.xml has autoOrients set to "true" and aspectRatio set to "landscape", I also tried deleting aspectRatio as suggested in some stackoverflow answer, to no avail.
StageOrientationEvent.ORIENTATION_CHANGING is never dispatched in my application.
Another weird thing is happening, which might help you understand the situation better:
Even though aspectRatio is set to "landscape" in application.xml, the app opens in portrait mode, and stage.orientation returns "rotatedRight" (meaning landscape).
I can only set to landscape properly by setting aspectRatio to "portrait" in application.xml, and then manually setting to "landscape" in runtime:
stage.setOrientation(StageOrientation.ROTATED_RIGHT);

If all you want is to lock landscape mode then first in description XML set aspectRatio to landscape and autoOrient to true then in code do:
stage.setAspectRatio(StageAspectRatio.LANDSCAPE);
stage.autoOrients = true;
And the device will not go through portrait.

<autoOrients>true</autoOrients>
<aspectRatio>landscape</aspectRatio>
should be the way to gay, it has always worked for us but we dont have published apps using this setting with air sdk 18
since it seems that it doesnt work for you, you may try the dynamic way as a workaround, like we use in our universal build (detects device iphone/ipad in preloader frame, applies correct orientation, instantiates the right main class), tested on old devices/os versions
with
<autoOrients>true</autoOrients>
<aspectRatio>any</aspectRatio>
and call stage.setAspectRatio(StageAspectRatio.LANDSCAPE); asap, meaning right in you main or preloader class constructor

Related

React native orientation is not working || locking on IOS

I created an app with React-native. All pages I made are designed for portrait mode except 1 page. The page accessibility comes from a button onPress then navigates to the page, so I can't lock orientation on Xcode
I installed this package and I can run it on android perfectly
import Orientation from 'react-native-orientation';
When I tried it on IOS simulator on every page it can turns orientation to landscape.
I put this line in every pages componentdidmount but nothing changes.
componentDidMount() {
Orientation.lockToPortrait()
...
}
What should I do?
Hey again #masterAvatarr,
I believe that this is what you're looking for, if you need something else please explain it to me :) We can make it happen.
I made a simple example for you.
https://github.com/WrathChaos/react-native-portrait-locker-example
I use React Native Orientation Locker Library
The important parts are:
Make sure that you linked the library manually (check AppDelegate.m)
You need to make a logic for unlocking and lock the portrait mode depends on your use-case
Please take a look at HomeScreen and DetailScreen
import Orientation from "react-native-orientation-locker";
React.useEffect(() => {
const unsubscribe = navigation.addListener("focus", () => {
// The screen is focused
// Call any action
Orientation.unlockAllOrientations();
Orientation.lockToPortrait();
});
// Return the function to unsubscribe from the event so it gets removed on unmount
return unsubscribe;
}, [navigation]);
Note: There is a little GIF Demo on the Github Repo

Phonegap landscape not detecting orientation for 90 and -90

I have a problem getting my iOS app to use landscape mode.
I'm new to phonegap, iOS, mac, and most of this stuff but have been searching the web for a few days now and I need help.
I'm using xcode 5, phonegap 2.3.0, and my intended target is iPhone iOS 7.
I have an app that is in production, and I need to give it some support for landscape.
In specific situations it should be possible to tilt the phone and get a better view.
I found this code:
window.addEventListener('orientationchange', doOnOrientationChange,true);
function doOnOrientationChange(e)
{
alert('orientation event fire');
switch(e.orientation)
{
case -90:
case 90:
alert('landscape');
break;
default:
alert('portrait');
break;
}
}
I can also use window.orientation instead of e.orientation.
This seams to be the popular way of handling this stuff.
For some reason the alert "orientation event fire" is only called when the phone is turned 180 and back to 0. No event is happening at 90 or -90.
I set the supported interface orientations, in xcode, to all 4 possibilities.
And in my index.html I have:
<meta name="viewport" content="user-scalable=yes, width=device-width" />
I can get the app to start in landscape mode but not change into it once the app is running.
It can change back to portrait mode just fine.
For some reason the phone is not telling me when it is at 90 and -90.
I read that it is not phonegap that is handling the rotation, but the browser that is used by phonegap. This is the behavior that I am looking for as I would like the browser to resize and rotate everything for me when the phone is tilted.
Also i'm reluctant to update phonegap as I have read many post about it handling rotation bad after version 2.3.0
Any ideas ??
EDIT:
Sometimes the answer comes to you, only once you asked the question on a forum.
The problem in my case was that another developer in my company had added:
function shouldRotateToOrientation(interfaceOrientation) {
return app.shouldRotateToOrientation( interfaceOrientation );
}
To my index.js file.
Apparently the shouldRotateToOrientation function is one that phonegap will look for in the code, and if it is there use to, limit the screen rotation.
I tried writing the following:
function shouldRotateToOrientation(interfaceOrientation) {
return true;//(1 === interfaceOrientation);
}
And everything worked fine.... Or one thing remains
The next problem is to find the current direction.
Apparently the value passed to shouldRotateToOrientation will indicate the current orientation. (The interfaceOrientation in my case)
Some write 1 means portrait and 2,3,4 refers to the other orientations.
Some write it returns 0, 90, -90, 180. (The last one I found to be true in my case.)
However it calls the function 4 times at each orientation shift.
So putting a console.log into the function will result in 4 lines being printed each time the phone is tilted.
The order in which the lines are printed are the same in each case, so no way of determining which way the phone is actually turning.
Someone gave this as a solution:
function changeOrientation() {
console.log(window.orientation);
}
window.onorientationchange = function () {
//Need at least 800 milliseconds
setTimeout(changeOrientation, 800);
}
But this is only called when the screen actually change orientation and I need something to tell me which way the phone is turning, so I can decide if I will allow an orientation change.
Also it is a bit annoying that it should be necessary to wait for 800 milliseconds.
Any idea how to get the current actual orientation of the phone. Not the orientation the app is rendered at??
EDIT:
I ended up using:
function shouldRotateToOrientation(newOrientation) {
return window.app.supportLandscape || !(interfaceOrientation%180);
}
For limiting the screen even though the newOrientation value is all over the place it still works. The window.app.supportLandscape is the one is set in my code where I want to support landscape or not. The !(interfaceOrientation%180) part allows me to rotate back to portrait in all cases.
If i go to a screen that is allowed to be landscape.
I turn the phone and go into landscape mode.
I then press the back button and go back to the page that should only be in portrait mode.
I see this page in landscape mode (cannot be helped)
I turn the phone back to portrait mode and the screen is now in portrait mode again, and locked to this mode.
The next problem I am facing is that on the devices landscape screen is not rerendered.
The graphics turn but it does not scale to fit the screen.
This behavior is only when I use Archive to generate an .ipa file, and deploy it through iTunes.
When launching directly from xcode 5 to the device or to any simulator, the graphics will fit to scale in landscape mode.
I found a post saying that the problem was xcode using different setups to generate .ipa files as opposed to launching the code. This is true as xcode uses debug when launching and release when archiving.
I tried to set archive mode to use debug but same problem.
I tried to set run to release but it still worked fine.
Any ideas ???
Use native code as plugin ad call it using javascript. also add it in config.xml. and in CDViewController change Autorotate - return NO. If you want a detailed solution then let me know. I have solved this same condition.
Update : my Solution
Create a new js file as ScreenOrientation.js and insert the below code,
var ScreenOrientation = {
//alert(orientation);
callScreenOrientationNative: function(success,fail,orientation) {
return Cordova.exec( success, fail,
"ScreenOrientation",
"screenorientationFunction",
[orientation]);
}
};
and add the above file in index.html as below,
<script type="text/javascript" src="ScreenOrientation.js"></script>
Add the below function in any added js file(in my project i have added a script.js file to add common functions),
function callScreenOrientation(orientation) {
ScreenOrientation.callScreenOrientationNative(nativePluginResultHandler,nativePluginErrorHandler,orientation);
}
function nativePluginResultHandler (result) {
}
function nativePluginErrorHandler (error) {
}
In config.xml add the below under feature name,
<!-- Screen Orientation custom plugin to display reports page. -->
<feature name="ScreenOrientation">
<param name="ios-package" value="ScreenOrientation"/>
</feature>
Under Plugins add (For cordova < 3.0),
<plugins>
<plugin name="ScreenOrientation" value="ScreenOrientation" />
</plugins>
On Cordova projects > Plugins right click and select new file, then from iOS select Cocoa touch then Select objective-C Class and click next, in class name insert "ScreenOrientation" and in Subclass of "CDVPlugin" and click next and click create.
Enter the below in ScreenOrientation.h,
#import <Cordova/CDV.h>
#interface ScreenOrientation : CDVPlugin
- (void) screenorientationFunction:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
#end
Enter the below in ScreenOrientation.m,
#import "ScreenOrientation.h"
#implementation ScreenOrientation
- (void) screenorientationFunction:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options {
[arguments pop];
NSString *orientation = [arguments objectAtIndex:0];
if ( [orientation isEqualToString:#"LandscapeLeft"] ) {
NSLog(#"Landscape Left");
[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationLandscapeLeft];
}
else if ( [orientation isEqualToString:#"LandscapeRight"] ) {
NSLog(#"Landscape Right");
[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationLandscapeRight];
}
else if ( [orientation isEqualToString:#"Portrait"] ) {
NSLog(#"Portrait");
[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortrait];
}
else if ( [orientation isEqualToString:#"PortraitUpsideDown"] ) {
NSLog(#"Portrait upSide Down Left");
[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortraitUpsideDown];
}
}
#end
In Cordova project click search and search for "shouldAutoRotate and find the below and change the return, by default it will be 'YES' change it to 'NO'.
CDVViewController.m
- (BOOL)shouldAutorotate
{
return NO;
}
And in project settings, in Device orientations check all options (not important though),
Project Settings > Device orientation > Tick all 4 options.
and call it from your project like this,
callScreenOrientation('LandscapeLeft');
callScreenOrientation('LandscapeRight');
callScreenOrientation('Portrait');
callScreenOrientation('PortraitUpsideDown');
In Xcode 5, select your target, click on the Info tab and make sure you've got the appropriate 'Supported Interface Orientations' selected. In my case, the Phonegap CLI produced a project that had only Portrait added to the orientation list -- even though I specified Landscape in config.xml
Screenshot:
http://i.stack.imgur.com/Bi8RC.png

Properly preventing orientation change in Flex Mobile app

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.

My Webview Reloads When I Change From Portrait To Landscape

I have a simple WebView that runs a web application on an Android. The problem is when I rotate the phone to change it to landscape the webview reloads and goes back to the beginning.
How can I prevent this action?
Ron
Beginning with Android 3.2 (API level 13), the "screen size" also
changes when the device switches between portrait and landscape
orientation. Thus, if you want to prevent runtime restarts due to
orientation change when developing for API level 13 or higher (as
declared by the minSdkVersion and targetSdkVersion attributes), you
must include the "screenSize" value in addition to the "orientation"
value. That is, you must decalare
<activity android:configChanges="orientation|screenSize">
Excerpt from Handle configuration changes (webarchive to original page)
This can be resolved by overriding onSaveInstanceState(Bundle outState) in your activity and calling saveState from the Webview:
This blog post may be of help to you.
Add the following to your AndroidManifest:
android:configChanges="orientation|keyboard|keyboardHidden"
So it should look something like this:
<activity android:name=".MyActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboard|keyboardHidden">
Obviously, if your WebView needs keyboard support then don't include the keyboard options.
Add this before the oncreate
#Override
protected void onSaveInstanceState(Bundle outState) {
webview.saveState(outState);
}
Write the oncreate this way. put final
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layoutname);
if (savedInstanceState != null)
{
((WebView)findViewById(R.id.webview)).restoreState(savedInstanceState);
}
else
{
webview.loadUrl("http://www.playbuzz.org/");
}
}
In Androidmanifest insert under the activity
android:configChanges="keyboardHidden|orientation"
#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
Add above method in your activity.. and
android:configChanges="keyboard|keyboardHidden|orientation"
in your manifest file
The problem with the above solution is that it renders the screen white for some time before the webview redraws the contents.
Try using
android:configChanges="orientation|keyboardHidden" inside your AndroidManifest.xml file for the activity that displays the webview. That should help.
Add in Activity
android:configChanges="keyboardHidden|orientation"

View Rotation in MonoTouch iPad Application

I'm pretty new to MonoTouch and I'm having problems getting my app to rotate from portrait to landscape mode.
My project has two XIB files, the MainWindow added by MonoTouch and MainController.xib which I have added. The MainController has a single label and no other controls. In my Main.cs I have the following to load the MainController.xib file:
UIViewController controller = new MainController();
window.AddSubview(controller.View);
In the MainController code I added
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
return false;
}
It all runs fine and the label displays but when I rotate the simulator nothing rotates. I'm sure it's something really simple that I'm getting wrong but I just can't seem to crack it.
Any help would be appreciated.
You can look at TweetStation for a sample.
In this particular case, you might want to return "true" instead of false in the sample above.

Resources