Xamarin Forms app not changing orientation on iOS - xamarin.forms

I have a Xam.Forms app which is working fine on iOS and Android with one exception. All screens except one are portrait. When this one screen shows, it show rotate to landscape. It works fine on android.
On iOS, it fails to change. The info.plist file has all orientations enabled. As I want only this one screen to be portrait, I have in the AppDelegate class an override that ensures everytrhing is portrait except one.
The override is this
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
{
var mainPage = Shell.Current?.CurrentPage;
if (mainPage != null)
{
if (mainPage is IDCardPage)
{
return UIInterfaceOrientationMask.Landscape;
}
}
return UIInterfaceOrientationMask.Portrait;
}
A break point for the landscape is hit, but there is no rotation. According to the Apple docs, this is all I should need to do to rotate a view

Related

android images in custom notification views inverse in dark mode (android 10.0)

when i use systemPic style,use system xml,it works well.
builder.setContentTitle(StringUtil.f(title));
builder.setContentText(StringUtil.f(desc));
if (poster != null) {
builder.setLargeIcon(poster);
}
Notification notification = builder.build();
but when i use custom layout, the image in notification like a negative image:
original image vs Invert image

How do I remove the extra padding when displaying the MasterDetail Master view

When opening the Master portion of a Xamarin Forms MasterDetail window in Landscape mode on iPhoneX it looks like the padding meant to accommodate the safe area is not removed, resulting in a huge gap between the hamburger and master view. This does not exist running on an iPhone 8.
iPhone X:
iPhone 8:
Also, the color of the safe area to the left of the master area is the same color as the detail view, how do I make the colors of the master view extend into this area?
For the color to extend you just have to set the background color of your page and as for the insets, you can adjust them.
public YourPage()
{
InitializeComponent();
On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(true);
BackgroundColor = Color.YourColor;
}
protected override void OnAppearing()
{
base.OnAppearing();
var inset = On<Xamarin.Forms.PlatformConfiguration.iOS>().SafeAreaInsets();
inset.Left = 24;
Padding = inset;
}
Keep in mind if your app can rotate between portrait and landscape you may have to override OnSizeAllocated to handle setting the insets there as well.

How to detect the screen the JavaFx app window is on and show dialogs there?

I've a JavaFx app which shows some alerts/dialogs, but in the multi-screen environment, when the app is moved to a secondary screen, those alerts/dialogs are still shown on the primary screen.
How can I (automatically) show those (non-modal) dialogs on the same screen the app is on?
You just have to set the owner of your dialog:
dialog.initOwner(primaryStage)
And make sure you don't call it before primaryStage.show()
To detect on which screen the app is showing, you can use the bounds of the primary screen:
private boolean isOnPrimaryScreen(double x) {
Rectangle2D bounds = Screen.getPrimary().getBounds();
return x <= bounds.getMaxX();
}
My non-primary screens are to the left of my primary screen, so their bounds have negative minX values. A stage on one of these screens will have a negative x value, so the method in the accepted answer will incorrectly return true. I use the Screen.getScreensForRectangle method. That method can potentially return more than one screen for an arbitrary rectangle, so I use code like the following when I only care about the upper left corner of my stage:
/**
* Returns the screen for the specified stage.
*
* #param stage the stage
* #return the screen for the specified stage
*/
#Nonnull
public static Screen getScreenForStage(#Nonnull Stage stage) {
for (Screen screen : Screen.getScreensForRectangle(stage.getX(), stage.getY(), 1., 1.)) {
return screen;
}
throw new NoSuchElementException("Cannot determine screen for stage.");
}

How to handle QML page orientation?

I'm developing a BlackBerry 10 mobile application using the Momentics IDE 2.1.2 (native SDK).
Let's start with the example of the "orientation handler" that I'm using for my layout :
attachedObjects: [
OrientationHandler {
id: handler
onOrientationAboutToChange: {
if (orientation == UIOrientation.Landscape) {
mainContainer.sideMenuLarge = ui.sdu(80.0)
mainEntryHeaderContainer.layoutProperties.spaceQuota = 1.6
mainEntryBodyContainer.layoutProperties.spaceQuota = 5.8
} else {
mainContainer.sideMenuLarge = ui.sdu(60.0)
mainEntryHeaderContainer.layoutProperties.spaceQuota = 1
mainEntryBodyContainer.layoutProperties.spaceQuota = 7.4
}
}
}
]
Like you see, when the app starts in portrait mode everything is cool, it should be because all the Controls Paddings and the Containers SpaceQuota things are initialized with values that it is compatible with the portrait mode, but when it starts in Landscape mode it is different thing, it will takes the initial values of the portrait mode until I switch to portrait mode and then return it to landscape mode.
How can I fix this ? And can I have 2 pages in 1 navigation pane with differents "OrientationSupport" ? I tried but it doesn't works; for example I'm in page 1 in landscape mode and then I opened the page 2 that support only the portrait mode, it switchs to portrait but when I came back to the previous page the OrientationSupport will be fixed in portrait mode (it does not handle the landscape mode anymore)
Page 1:
OrientationSupport.supportedDisplayOrientation = SupportedDisplayOrientation.All
Page 2:
OrientationSupport.supportedDisplayOrientation = SupportedDisplayOrientation.DisplayPortrait

How to differ between phones and tablets while developing in Flex mobile?

I use applicationDPI in a Flex mobile card game:
<?xml version="1.0" encoding="utf-8"?>
<s:ViewNavigatorApplication
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
firstView="views.Menu"
applicationDPI="160"
initialize="init()">
<fx:Style source="Preferans.css" />
<fx:Script>
<![CDATA[
import spark.core.ContentCache;
public static const AVATAR_CACHE:ContentCache = new ContentCache();
public static var SCALE:Number;
public function init():void {
SCALE = runtimeDPI / applicationDPI;
}
]]>
</fx:Script>
</s:ViewNavigatorApplication>
And provide assets in 3 different resolutions based on it:
<fx:Declarations>
<s:MultiDPIBitmapSource id="BACK"
source160dpi="#Embed('assets/icons/low-res/back.png')"
source240dpi="#Embed('assets/icons/mid-res/back.png')"
source320dpi="#Embed('assets/icons/high-res/back.png')"/>
</fx:Declarations>
And still the result doesn't look good, when I for example select an iPad emulator in the Flash Builder 4.6:
While selecting Google Nexus One produces better result:
What to do here, what to use for detection of a phone vs tablet device?
Checking screen resolution wouldn't help here - see the above iPad example (low resolution, but big screen).
public static function get isTablet():Boolean
{
var deviceWidth:Number = Capabilities.screenResolutionX / Capabilities.screenDPI;
var deviceHeight:Number = Capabilities.screenResolutionY / Capabilities.screenDPI;
var diagonalInches:Number = Math.sqrt((deviceWidth * deviceWidth)+ (deviceHeight * deviceHeight));
if(diagonalInches>=7)
return true;
else
return false;
}
For a project I did for work, I had to evaluate the exact same issue. To do so, I created a new class that was run on app init that would evaluate the device and make some decisions.
Essentially, I did this
var deviceWidth:Number = Capabilities.screenResolutionX / Capabilities.screenDPI;
var deviceHeight:Number = Capabilities.screenResolutionY / Capabilities.screenDPI;
That will give you the device width and height on the majority of devices. The screenDPI property is not always accurate, however, so this will not work 100% of the time. It works often enough, however, that I don't think it is an issue.
From there, I did some research. I found that point where a phone stopped being a phone and started being a tablet. There is no standard approach, so I took the smallest popular tablet I could find (at the time, the Blackberry Playbook or Kindle Fire, can't remember which), and used the dimensions of that screen as the breakpoint between phone and tablet.
if ( deviceWidth >= fireWidth && deviceHeight >= fireHeight ) {
isTablet = true;
}
else {
isPhone = true;
}
That's pseudo code, obviously, but you get the idea. I also threw in some checks to distinguish between each platform (iOS, Android, and Desktop) and, if it was iOS, I manually set whether it was a tablet or phone because there is a limited field of devices there.
From there, I had two interfaces. One for phones, one for tablets. In the addedToStage function for my Application class, I used the isPhone and isTablet checks to choose which interface to load.
Probably not how it is supposed to be done, nor is it fool proof. Unfortunately, though, that is the closest we can get to a universal application with device-specific interfaces in Adobe AIR, as far as I am aware.

Resources