hasDifferentColorAppearance is true when app is backgrounded - ios13

Apple recommends that we use traitCollectionDidChange and compare trait collections using hasDifferentColorAppearance to catch when dark mode is toggled, and act on it if we need to. Like this:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 13.0, *) {
let hasUserInterfaceStyleChanged = previousTraitCollection?.hasDifferentColorAppearance(comparedTo: traitCollection) ?? false
if (hasUserInterfaceStyleChanged) {
//Update UI
}
}
}
I use this to update the UI, clear some caches etc when switching between dark and light mode.
For some reason traitCollectionDidChange fires and hasDifferentColorAppearance evaluates to true every time my app is backgrounded, no matter if I have dark mode enabled on the device or not. It seems the previousTraitCollection and the current traitCollection never have matching interfaceStyles in this case. I would rather avoid doing the updates I do when the userInterfaceStyle changes if the userInterfaceStyle hasn't actually changed.
Is this a bug, or am I just missing something?

iOS is creating snapshots of your UI for light and dark appearance (and also for portrait and landscape orientation) every time the app is backgrounded for previewing your app in the app switcher UI. So this is perfectly normal behavior.

Related

How to prevent dark mode flickering on a website?

I have implemented a dark mode to a WordPress site using a simple technique like this one found in https://github.com/avecNava/dark-mode.
<script>
//runs on every page load, checks local storage for last mode and applies dark mode if found
document.body.classList.toggle('dark-mode', localStorage.getItem('darkmode') === 'true');
//the function must be called when dark mode is clicked by the user
function switch_mode(){
const dark = localStorage.getItem('darkmode') === 'true';
localStorage.setItem('darkmode', !dark);
const element = document.body;
element.classList.toggle('dark-mode', !dark);
}
To prevent flickering I've tried to place the first row inside the head tags (via header and footer scripts plugin) but it doesn't seem to work. I've seen solutions to this problem but they all seem to be built different from the start so it's hard to apply those solutions to the code I'm using.
To trigger the switch, I'm using a clickable icon that has an onClick() property that calls the function. Is there any solution to my problem or should I just start the whole thing from scratch using a different technique for example a checkbox trigger?

"slotchange" event doesn't trigger at iOS 11

I need to detect the moment when a slot content rendered into my web component. I use slotchange event to track it. It works fine for all the browsers except iOS 11 (for iOS 13+ works ok). Could someone suggest how to do it properly?
So from the next code, I expect to see "firstUpdated" and "slotchange" messages in the console after the page is rendered. But for iOS 11 I have only "firstUpdated".
firstUpdated() {
console.log("firstUpdated");
const slot = this.shadowRoot.querySelector("slot");
slot.addEventListener("slotchange", () => {
console.log("slotchange");
});
}
Here is a sandbox:
https://codesandbox.io/s/minimal-litelement-vanilla-wy61t?file=/src/index.js
and URL to see the result:
https://wy61t.csb.app/
Older versions of Safari handled slot change events wrong - firing them before the elements were added to the DOM. I think firstUpdated is firing after the slot change has. Try using #slotchange=${... syntax instead, though even if that works it will fire out of order.
If that fails you may have check for the assignedElements manually to work around the Safari bug.

Handle orientation's change when device's auto rotate's feature is disabled in Flex 4.6

"StageOrientationEvent.ORIENTATION_CHANGE" event does not fire (dispatch) when the Auto Rotate feature of the device is disabled.
I'm developing a game that only must work on PORTRAIT mode. I speculate many users unchecked this option display settings.
How can I detect screen rotation regardless of device setting. Should I use accelerometer for this purpose or there is a better way?
If your game must always work in PORTRAIT mode; then you don't have to worry about device orientation changes. What you want to do is make sure your game always launches in portrait mode despite what the device settings are.
In the Application Descriptor file; set these values:
<aspectRatio>portrait</aspectRatio>
<autoOrients>false</autoOrients>
The application descriptor file is the "MainApplication-app.xml' file that Flash Builder will create as you create your main application.
In documentation theory those changes should do it; but if memory serves me I had problems in some versions of Android, where the app launched in the wrong orientation and would not change.
So, inside my application I added applicationComplete and activate handlers on my main application file and used those methods to specify the aspect ratio of the game. Something like this:
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
applicationComplete="viewnavigatorapplication1_applicationCompleteHandler(event)"
activate="viewnavigatorapplication1_activateHandler(event)">
<fx:Script><![CDATA[
import mx.events.FlexEvent;
protected function viewnavigatorapplication1_applicationCompleteHandler(event:FlexEvent):void{
this.stage.setAspectRatio( StageAspectRatio.PORTRAIT);
}
protected function viewnavigatorapplication1_activateHandler(event:Event):void{
if(this.stage){
this.stage.setAspectRatio( StageAspectRatio.PORTRAIT );
}
}
]]></fx:Script>
</s:ViewNavigatorApplication>
I have no memory of testing this specific use case on iOS Devices; so it is possible I only had the problem on Android. Or it is possible I did the Android code first and that is why I never had a problem on iOS.
Although I have used this method, I cannot take credit for it but please see: Please see this thread
Remember if you are developing for iOS, you CANNOT LOCK Device Orientation. You HAVE to add event listeners to handle orientation changes for iOS. The very first app I did got rejected for trying to lock orientation.

Custom URL issue in flex ios app

i am using custom url scheme in my flex iOS app and it’s working fine when i start my app from a web link..but the issue is when i start my app from start menu in iPad and move to webpage in safari.In page i click a button that redirects it to my app, at that time app call “preinitialize” method more than once..it wary every time, some time it’s 2,3,4 and different one each time..i don't know why it’s behaving like this..can i know the reason please its urgent..
thanks…any help will be appreciated.
Create a flag initialized and set it to true when preinitialize is called. All other calls to this method can be filtered out. Simple example:
private var initialized:Boolean = false;
public function preinitialize():void
{
if (initialized) return;
initialized = true;
}
Next step would be finding the real cause of the multiple calls, but for that we would need to see some code of your app.

How do you bring a visible NativeWindow to the front of all applications in a Adobe AIR App

The application I'm working on is a HTML AIR application based on the AIR 2.5 SDK.
The application starts two windows: the first is a hidden window that registers it's self on the system tray (it's windows specific); the second is a visible lightweight window displaying showing various bits of information. Since the visible window is lightweight, there is no task bar entry to always the user bring the window to the front if hidden under other application windows.
The requirement is that on clicking the system tray icon the display window will be brought to the front.
My current solution looks something like:
function handleClick(){
var nativeDisplayWindow = findDisplayWindow();
nativeDisplayWindow.alwaysInFront = true;
nativeDisplayWindow.alwaysInFront = false;
}
function findDisplayWindow(){
// looks in air.NativeApplication.nativeApplication.openedWindows for the
// the display window and returns it
}
It works but really doesn't feel right.
I've tried using NativeWindow.orderToFront() & NativeWindow.activate() and various combinations of all the other method.
Is this the correct way to bring a window to the front of all application windows in AIR?
If you try casting your nativeDisplayWindow as a Window you should then be able to do something like:
function handleClick(){
var nativeDisplayWindow:Window = findDisplayWindow() as Window;
nativeDisplayWindow.orderToFront();
}
I don't know if this is what you are looking for or whether I've just repeated what you've explained?

Resources