How to turn window background black on showing modal view in nativescript - nativescript

As shown in the image 1 below, when the modal view on ios 13 shows up, the default background is black. But on nativescript, the default background is white as shown in the image 2. How to achieve the image 1 kind of background (black) using nativescript core? I tried changing the color of status bar but that actually changes the color of the top page portion that's partially visible in the images. I tried to define background-color on Frame css, but didn't work. Any suggestions? Thanks in advance.
Image 1:
Image 2:
The modal view options:
const option: ShowModalOptions = {
context: { selectedAccount: account },
closeCallback: (a, b, c, action) => {
//some code
},
fullscreen: false
};
mainView.showModal("./modal-add-page", option);

You have to set the background color of window on iOS.
Update: Nativescript 7
import * as app form "#nativescript/core/application";
import { Color } from "#nativescript/core/color";
import { isIOS } from '#nativescript/core';
if (isIOS) {
if (app.hasLaunched) {
app.ios.window.backgroundColor = new Color("black").ios;
} else {
app.on("launch", _ => app.ios.window.backgroundColor = new Color("black").ios)
}
}
Older versions:
import * as app form "tns-core-modules/application";
import { Color } from "tns-core-modules/color";
// You must run it once application is initiated
app.ios.window.backgroundColor = new Color("black").ios;

Related

How to keep newly opened macOS window in front & prevent being hidden with SwiftUI?

I am using SwiftUI to create a macOS app and need to create a new window that opens with an image inside of it, which I am successfully accomplishing currently.
However, if I click back on the main app window, the newly opened window goes to the background and is hidden (normal behavior), however, I want the newly opened window to always be on top of the main app window AFTER if I click back on the main application window.
The reason is that the new window (WindowGroup) opened contains an image with the information I need to enter in the main app so if it goes behind the main app window, I can't see the image anymore.
Is there a WindowGroup modifier I can implement so that after the WindowGroup("imageView") window opens, it is always on top & how can I integrate into my existing code?
Thank you!
#main
struct customApp: App {
#StateObject var session = SessionStore()
var body: some Scene {
WindowGroup("mainView") {
ContentView().environmentObject(session)
}.handlesExternalEvents(matching: ["mainView"])
WindowGroup("imageView") {
ImageView(url: SessionStore.imageUrl)
}.handlesExternalEvents(matching: ["imageView"])
}
}
View that opens new window
struct ImageViews: View {
#Environment(\.openURL) var openURL
var body: some View {
HStack {
WebImage(string: idUrl)
.onTapGesture {
guard let url = URL(string: "app://imageView") else { return }
openURL(url)
}
}
}
}
Set the window.level to always on top .floating. You can access it via NSApplication.shared.windows.
Button("Window level") {
for window in NSApplication.shared.windows {
window.level = .floating
}
}

Change the color of the dialog buttons in iOS?

Is there a way to change the text color of the dialog buttons in iOS?
I mean for the OK/Cancel buttons at the bottom for the alerts/confirm dialogs etc.
If native code, that's ok also.
You will be needing to use native code if you want to achieve this on IOS, here's how you can do it:
if (isIOS) {
var alertController = UIAlertController.alertControllerWithTitleMessagePreferredStyle("title", "message", UIAlertControllerStyle.ActionSheet);
// Here are some premade styling. The destructive by default is red on IOS. You can select default for them all or use existing.
var editAction = UIAlertAction.actionWithTitleStyleHandler("Edit", UIAlertActionStyle.Default, (arg: UIAlertAction) => {
//code implementation here
});
var deleteAction = UIAlertAction.actionWithTitleStyleHandler("Delete", UIAlertActionStyle.Destructive, (arg: UIAlertAction) => {
//code implementation here
});
var cancelAction = UIAlertAction.actionWithTitleStyleHandler("Cancel", UIAlertActionStyle.Cancel, (arg: UIAlertAction) => {
//code implementation here
});
alertController.addAction(editAction);
alertController.addAction(deleteAction);
alertController.addAction(cancelAction);
// This is how you can force change the color of the title text on the actions (buttons).
alertController.view.tintColor = new Color("#FF0000").ios; // Color is a class in Nativescript, if we you want the Native IOS value, this is how you do it.
var currentPage = topmost().currentPage;
var viewController: UIViewController = currentPage.ios;
viewController.presentModalViewControllerAnimated(alertController, true);
}
Make sure you imported what's needed:
import { isIOS, Color } from 'tns-core-modules/ui/page/page';
import { topmost } from 'tns-core-modules/ui/frame';
There are other styling customizations you can do by changing the default alertController.view settings. So just try out what's best for your use case.

How to disable SwiftUI animations in UITests?

I tried to disable animation in UITests with the following code:
let app = XCUIApplication()
app.launchEnvironment = ["DISABLE_ANIMATIONS": "1"]
I also tried:
UIView.setAnimationsEnabled(false)
But it doesn't disable animation when I run UITests on simulator.
Is it because I'm using SwiftUI ?
The animation I want to disable is a view transition from one SwiftUI View to another one. Here is how I coded the transition:
NavigationLink(destination: MapView(), isActive: $viewModel.isDataLoaded) {
EmptyView()
}
Is there another way to disable animation in UITests when using SwiftUI ?
It is needed to be done explicitly (by-code) in main application, because UITests run in different process, ie. it should be like
struct YourApp: App {
init() {
let env = ProcessInfo.processInfo.environment
if env["DISABLE_ANIMATIONS"] == "1" { // << here !!
UIView.setAnimationsEnabled(false)
}
}
var body: some Scene {
// ... scene here
}
}
and then it can be used
let app = XCUIApplication()
app.launchEnvironment = ["DISABLE_ANIMATIONS": "1"]
Tested with Xcode 13.3 / iOS 15.4

How to properly reference modals as of NativeScript 4

I have built an app with NativeScript Angular (now on v4.1). I am using the code below to set a status bar color on Android, which works fine for "regular" views by using angular routing:
if (isAndroid) {
if (app.android && device.sdkVersion >= '21') {
const nativeColor = new Color('purple').android;
const window = app.android.startActivity.getWindow();
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
app.android.startActivity.getWindow().setStatusBarColor(nativeColor);
}
}
However, it does not work in a modal, where the colored status-bar turns to black. Anyone any ideas why this is? My best guess would be that a modal is not referenced by app.android.startActivity.getWindow() but I’m unclear as how to get it.
Not sure to what extent this is related, but also I am unable to set a different loading indicator on iOS in modals by using this code from the docs (again works fine in non-modal views):
if (isIOS) {
var indicator = this.page.getViewById("spinner");
indicator.ios.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge;
}
Thanks for any pointers!
P.S.
Here is a demo project which displays the problem both with the status bar on Android, as well as not being able to set the activity indicator on iOS.
For anyone reading this later on: I had some help on the NativeScript forum and did not yet accomplish setting the statusbar color on the modal, but I was able to span the background under the status bar in the modal component which is good enough for my purposes.
I was also able to change the ActivityIndicator in the modal simply by using an Angular ViewChild on the indicator element instead of finding it through Page (which turns out does not refer to the modal).
import { Component, OnInit, AfterViewInit, ViewChild, ElementRef } from "#angular/core";
import { ModalDialogParams } from "nativescript-angular/modal-dialog";
import { isIOS, isAndroid, device } from 'platform';
import * as app from "application";
declare var UIActivityIndicatorViewStyle: any;
declare var android: any;
#Component({
template: `
<StackLayout #root>
<StackLayout orientation="horizontal">
<ActivityIndicator #spinner id="spinner" busy="true"></ActivityIndicator>
<ActivityIndicator busy="true"></ActivityIndicator>
</StackLayout>
</StackLayout>
`
})
export class ModalTest implements OnInit, AfterViewInit {
#ViewChild('root') root: ElementRef;
#ViewChild('spinner') spinner: ElementRef;
constructor(
public modalParams: ModalDialogParams
) {}
public ngOnInit() {
/* show large activity indicator on iOS */
if (isIOS) {
this.spinner.nativeElement.ios.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge;
}
}
public ngAfterViewInit() {
if (isAndroid) {
setTimeout(() => {
if (app.android && device.sdkVersion >= '21') {
const dialog = this.root.nativeElement._dialogFragment.getDialog();
const window = dialog.getWindow();
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
},1);
}
}
public closeModal() {
this.modalParams.closeCallback();
}
}

How to have dynamic image on Xamarin Form Header?

I am working on Xamarin form in which header title will have weather temperature and weather icon on its right side.
For example
New York 60' F SunnyIcon
I am using openweather api to fetch the data.
Problem is, I am not able to create a dynamic image holder on the Xamarin Form Header.
How to have a dynamic image on the Xamarin Form Header?
Attached is a sample app which i am working on based on source code which i downloaded from github ...
I'm not sure what you mean by "Header," but if you're trying to add an icon to the Navigation Bar, you can do that by calling ToolbarItems.add() in the constructor of your page like this:
public myPage()
{
InitializeComponent();
ToolbarItems.Add(new ToolbarItem("Weather", "WeatherIcon.png", async () =>
{
//Code to Execute when Icon is tapped
}));
}
When adding the ToolbarItem, the first parameter is the name of the item, the second is the name of the image that will be displayed at the end of the Navigation bar, and the last one is optional which creates a method that is executed when the icon is tapped.
If you need the icon to be different depending on the current weather, you can do that like this:
public myPage()
{
InitializeComponent();
string weatherIconString = "";
if(weather.isSunny) // Edit contition however you need
weatherIconString = "SunnyIcon.png";
else
weatherIconString = "CloudyIcon.png";
ToolbarItems.Add(new ToolbarItem("Weather", weatherIconString));
}
You have to write a custom renderer like this: and the result:
public class CustomNavigationPageRenderer : NavigationRenderer
{
public override void ViewDidLoad()
{
//I'm getting width and height so i can rescale the image
nfloat navigationBarWidth = NavigationBar.Frame.Width;
nfloat navigationBarHeight = NavigationBar.Frame.Height;
//you can load image from your bundle,so you can add your weather icons on bundle -> under Resources folder
var img = UIImage.FromBundle("navigationbarbackground.jpg");
//create image context to draw image
UIGraphics.BeginImageContextWithOptions(new CGSize(navigationBarWidth, navigationBarHeight), true, 0);
//I'm filling the background with a color so it is the same as with my background image color
UIColor.FromRGB(54, 60, 65).SetFill();
UIGraphics.RectFill(new CGRect(0, 0, navigationBarWidth, navigationBarHeight));
//draw your image according to the coordinates of the navigation bar, i put it to the right top with a small right padding,
//you have to play with coordinates according to your needs
img.Draw(new CGRect(navigationBarWidth - navigationBarHeight - 30,//move 30px to the left (do not paste to right border :))
0, navigationBarHeight, navigationBarHeight));
UIImage backgroundImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
NavigationBar.SetBackgroundImage(backgroundImage, UIBarMetrics.Default);
//bonus :) change your title color
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes()
{
TextColor = UIColor.White,
});
base.ViewDidLoad();
}
}

Resources