iOS overrides the `navBarButtonColor` when using PNGs - ios

Issue Description
In my application I have a navigation bar search button set up as follows:
static navigatorButtons = {
leftButtons: [
{
id: 'back-nav-button',
icon: require('../assets/images/icons/arrow-left.png')
}
]
};
The button works as intended on both iOS and Android, but the button is blue on iOS. I understand that this is the desired behavior and that the color can be overridden by setting navBarButtonColor, but the problem is that it's a multi-colored button - meaning I want then button to simply contain the PNG image's colors, and not the navBarButtonColor.
I've tried setting navBarButtonColor to null, transparent, but nothing seems to work.
So my question is, is there a way to make navigation bar icons take on the color of the PNG provided, as is the case on Android?
Steps to Reproduce / Code Snippets / Screenshots
Simply run any RNN app on iOS with a simple static navigatorButtons = ... using a local multi-colored PNG and you'll see the colors of the icon get overwritten.
Environment
React Native Navigation version: 1.1.473
React Native version: 0.55.3
Platform(s) (iOS, Android, or both?): iOS
Device info (Simulator/Device? OS version? Debug/Release?): Android Emulator on Debug

On iOS, UIBarButtonItem uses images created with source image's alpha channel. To display the actual image (not an alpha channel mask of it) you need to change your image's rendering mode to alwaysOriginal
Although, looking at React Native Image class documentation I can't see renderingMode property

We've managed to find a workaround for this. By setting the disableIconTint button property to true, it disables the icon color override. See the following example:
static navigatorButtons = {
leftButtons: [
{
id: 'back-nav-button',
icon: require('../assets/images/icons/arrow-left.png'),
disableIconTint: true // Add this line to use the PNG's color
}
]
};

Related

How can I access UIImage dark appearance pre iOS13

I've just added dark mode to my app.
Asset catalogs support multiple appearances for each asset, on iOS 13 this means the correct asset is used when the system is running in dark or light mode.
These are not my real assets
I'm trying to support dark mode on older iOS versions.
In my attempts to do so, I have added an override to force dark mode which works for my custom colours and theming but not for the images.
Is it possible to access the dark appearance of an image programatically before iOS13?
For iOS12 I have tried using the following:
if #available(iOS 12.0, *) {
let traits = UITraitCollection(userInterfaceStyle: .dark)
let image = UIImage(
named: "Image",
in: bundle,
compatibleWith: traits
)
}
This only returns the normal appearance, and the method naming seems to suggest this only checks that the trait collection I've passed is compatible with the image.
As far as I know, there's no way to do that with just one asset. Below iOS 13 the system will always take the Any appearance. You would need to create two different image sets with different names and choose either one of them.
It is a bit confusing since UIUserInterfaceStyle is available in iOS 12+, but this is likely because macOS got Dark Mode that year.

Ios webview with capacitor, set safe areas

Using capacitor to build an app in ios. In ios the webview covers the whole screen, for iphone-x that means the notch will be included and content will go behind it, like the picture on the right. But i want the picture on the left, black bars on 'no go areas'.
The expected solution (html/css) for this would be to set correct viewport and use the 'safe-area'insert-?', se: https://css-tricks.com/the-notch-and-css/
But for the webview in ios the 'safe-area'insert' will always be 0, that is how it works => this solution is useless.
How can i solve this? Can i change the webview to not cover the whole screen, without changing in the capacitor-framework?
You can use a compatible Cordova plugin cordova-plugin-safearea
npm i -D cordova-plugin-safearea
npx cap sync
With this installed, you can request the safe margin area over the cordova/capacitor bridge:
// Types for clarity
type SafeArea = {
top: string,
bottom: string,
}
window.plugins.safearea.get(
(result: SafeArea) => {
// elegantly set the result somewhere in app state
},
(error: any) => {
// maybe set some sensible fallbacks?
}
);
You could use these values to specify extra padding on the body, or on your header / bottom-menu components
The docs say it returns the values as Numbers, but it seems to me they are actually strings (consider parseFloat before doing math with them).
I have just implemented this in React (running the getter in React.useLayoutEffect); the project is wrapped in Capacitor and have tested on two iOS devices with different ingenious Apple notch screen formats (iPhone 8 and iPhone 11 Pro).
Refer to the documentation for more at https://github.com/rickgbw/cordova-plugin-safearea
There is a CSS variable preset by capacitor you can use to set the padding or a margin for example.
html {
--ion-safe-area-top: env(safe-area-inset-top);
--ion-safe-area-bottom: env(safe-area-inset-bottom);
--ion-safe-area-left: env(safe-area-inset-left);
--ion-safe-area-right: env(safe-area-inset-right);
}

How do I change the color of the push notification icon in flutter? [duplicate]

I tried making the small icon exactly 16x16, gray-scaled, nothing but gray and white (the gray color being hex value 616161), to create a silhouette of my application icon.
Yet no matter what it just shows up as a white/gray square in the notifications. What am I doing wrong?
(My min api is 21, assuming it is relevant)
Follow this link
First let’s understand the Android documentation which is as follows
“Update or remove assets that involve color. The system ignores all
non-alpha channels in action icons and in the main notification icon.
You should assume that these icons will be alpha-only. The system
draws notification icons in white and action icons in dark gray.”
Now this is easy to miss and I have seen many apps that are live in the app store with thousands of users who haven’t followed the mentioned guidelines.
So let me explain in detail how you can convert your notification icon to an Android friendly one with a few clicks.
In your favourite image editor open up your icon file. Convert all parts of the image that you don’t want to show to transparent pixels. All colors and non transparent pixels are displayed in white. Let us go through an example.
EDITED: Thanks #Andrey Patseiko for the tool
For notification you have to use different icons for different versions of android:
Notification notification = new Notification.Builder(context)
.setAutoCancel(true)
.setContentTitle("My notification")
.setContentText("Look, white in Lollipop, else color!")
.setSmallIcon(getNotificationIcon())
.build();
return notification;
Get notification icon on the basis of version
private int getNotificationIcon() {
boolean useWhiteIcon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
return useWhiteIcon ? R.drawable.icon_silhouette : R.drawable.ic_launcher;
}
Along with new features and capabilities, Android 5.0 includes a variety of system changes and API behavior changes. See the notification behavior changes.
Notifications are drawn with dark text atop white (or very light)
backgrounds to match the new material design widgets. Make sure that
all your notifications look right with the new color scheme. If your
notifications look wrong, fix them:
Use setColor() to set an accent color in a circle behind your icon image.
Update or remove assets that involve color. The system ignores all non-alpha channels in action icons and in the main notification icon.
You should assume that these icons will be alpha-only. The system
draws notification icons in white and action icons in dark gray.
So, basically you have to use silhouette icons as notification icon for API Level 21+

UIImage looks different when used in iOS

I am having problems with a png image, that gets wrong colors on iOS compared to the actual image.
It does not matter how I am using the image, it always gets the wrong colors. I have tried on UIButton and UIImageView and it gives the same result.
It is a very standard use of a UIImage:
UIImage* greenButtonImg = [UIImage imageNamed:#"btn_green"];
UIImageView* testView = [[UIImageView alloc] initWithImage:greenButtonImg];
[self.view addSubview:testView];
The second image is how it looks on iOS and the first button is how it looks on my Mac (Finder and Photoshop):
As you can see the second button has a different green color.
This is happening all over the app where am using this picture. It happens in the Simulator and on a iPhone 5.
What can cause this issue? Can this be caused by settings in Photoshop, where the image was created?
As Jeff wrote in a comment it was a problem with the RGB Profiles.
I managed to fix the problem by converting the color profile in Photoshop:
Edit -> Convert to Profile... -> Set profile to "Apple RGB"
In iOS 7.0, the image is colored with the toolbar’s tintColor.
In iOS 7.0, all subclasses of UIView derive their behavior for tintColor from the base class.
By default, an image (UIImage) is created with UIImageRenderingModeAutomatic.
If you have UIImageRenderingModeAutomatic set on your image, it will be treated as template or original based on its context.
Certain UIKit elements—including navigation bars, tab bars, toolbars, segmented controls—automatically treat their foreground images as templates, although their background images are treated as original.
Other elements—such as image views and web views—treat their images as originals. If you want your image to always be treated as a template regardless of context, set UIImageRenderingModeAlwaysTemplate.
If you want your image to always be treated as original, set UIImageRenderingModeAlwaysOriginal.
Refer Template Images for more info.

White background on windows explorer context menu Icon

I have a COM shell extension that adds an item to the Windows Explorer context menu and use a BMP image with a transparent background as the icon.
To set the image I use SetMenuItemBitmaps like so:
[DllImport("user32.dll", ExactSpelling = true)]
internal static extern int SetMenuItemBitmaps(IntPtr hMenu,uint uPosition,uint uFlags,IntPtr hBitmapUnchecked,IntPtr hBitmapChecked);
SetMenuItemBitmaps(owner.hMenu,(uint)pos,Win32.MF_BYPOSITION,bitmap.GetHbitmap(),IntPtr.Zero);
My problem is this - when the icon first appears it looks fine but after hovering above it the icon's background becomes white (instead of transparent) and remains white until I reopen the menu.
I have tried setting both non default values in the parameters "hBitmapUnchecked", "hBitmapChecked" - but it doesn't seem to make any difference. The outcome remains the same.
This is the icon image before the hover (zoomed to 400%):
This is the icon image after the hover:
Note the white background around the second image!
So far, I've failed to find anything relevant on google.
Is there some other way to set the icon to avoid this annoying background?

Resources