I want set the NavigationBar/ActionBar Color to Transparent/Clear in Nativescript.
import {BasePage} from "../../shared/BasePage";
import frameModule = require("ui/frame");
import {topmost} from "ui/frame";
import {Observable, EventData} from "data/observable";
import {View} from "ui/core/view";
class HomePage extends BasePage{
mainContentLoaded(args:EventData){
let view = <View>args.object;
if(view.ios){
var controller = frameModule.topmost().ios.controller;
controller.navigationBar.barTintColor = UIColor.redColor();
}
view.bindingContext = new Observable({ myText: 'This is the home page' });
}
}
export = new HomePage();
But i get this error: "error TS2304: Cannot find name 'UIColor'"
What i doing wrong?
Thanks for help
I suggest you to use the NS color module and convert it to iOS color, so that you can use any color that you want. Like this:
var colorModule = require("color");
var red = new colorModule.Color("#ff0000");
var controller = frameModule.topmost().ios.controller;
controller.navigationBar.barTintColor = red.ios;
Related
[Hi, I am trying to add texture to 3d modal loaded through useLoader i use primitive that react three fiber provides and when i add map prop and pass img to it, it doesn't work. please help me][1]
import { useLoader, useFrame } from '#react-three/fiber'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import { Environment, OrbitControls, OrthographicCamera } from "#react-three/drei";
import { Canvas } from "#react-three/fiber";
import { useState, Suspense } from "react";
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { Texture, TextureLoader } from "three";
import Wrapper from "../assets/wrapper.jpg";
const Scene = () => {
const ref = useRef();
useFrame(() => {
// ref.current.rotation.z += 0;
ref.current.rotation.y += 0.01;
// ref.current.rotation.x = 0.09;
// ref.current.rotation.x += -170;
});
const img = useLoader(TextureLoader, Wrapper);
const obj = useLoader(OBJLoader, 'fibbia_wrap.obj');
return (
<>
<primitive map={img} ref={ref} object={obj} scale={0.6} />
</>
)
}```
[1]: https://i.stack.imgur.com/KixV1.png
In this case, don't use primitive.
1) First, export your modal in.glb form.
2) Then use gltfjsx package, this package will auto-generate JSX code for your modal.
Which then you can use. In order to learn more about this package go to (https://github.com/pmndrs/gltfjsx).
3) After that you are good to go the gltfjsx package provides code consisting of mesh and mesh can take map property which primitive can't.
By attaching an event listener to the loaded-event on Page and getting the NativeView-object I've been able to set the prefersLargeTitle to true:
loaded(event){
const page = event.object;
if (isIOS) {
page.frame.ios.controller.navigationBar.prefersLargeTitles = true;
}
}
This works, but I would like to change the font-family of the large title. How can I do this in Nativescript?
Try adding the code below to your app.js
import {
isIOS
} from "tns-core-modules/platform";
import {
ActionBar
} from "tns-core-modules/ui/action-bar";
import {
Font
} from "tns-core-modules/ui/styling/font";
if (isIOS) {
ActionBar.prototype.originalSetColor = ActionBar.prototype.setColor;
ActionBar.prototype.setColor = function (navBar, color) {
ActionBar.prototype.originalSetColor.call(this, navBar, color);
var newDict = {
[NSFontAttributeName]: Font
.default
.withFontFamily(
"yourFontFamily")
.withFontSize(yourFontSize)
.getUIFont(UIFont
.systemFontOfSize(20)),
};
if (navBar.largeTitleTextAttributes) {
newDict[NSForegroundColorAttributeName] = navBar.largeTitleTextAttributes.valueForKey(NSForegroundColorAttributeName);
}
navBar.largeTitleTextAttributes = newDict;
};
}
You may still set the prefersLargeTitles flags as you are doing already.
Here's what I have so far. The background goes green (the colour of the Page), but I'd expect a purple ContentView with some text inside to fill the page, too.
Is there anything further I'm missing?
import { on, run, launchEvent } from "tns-core-modules/application";
import { Frame } from "tns-core-modules/ui/frame/frame";
import { ContentView } from "tns-core-modules/ui/content-view/content-view";
import { TextBase } from "tns-core-modules/ui/text-base/text-base";
import { Page } from "tns-core-modules/ui/page/page";
on(launchEvent, (data) => {
const frame = new Frame();
const page = new Page();
page.backgroundColor = "green";
const contentView = new ContentView();
const textBase = new TextBase();
contentView.height = 100;
contentView.width = 100;
contentView.backgroundColor = "purple";
textBase.text = "Hello, world!";
contentView._addView(textBase);
page.bindingContext = contentView;
frame.navigate({ create: () => page });
data.root = page; // Incidentally, should this be the frame or the page?
});
run();
You are almost on track, you just need slight modification on your code.
import { on, run, launchEvent } from 'tns-core-modules/application';
import { Frame } from 'tns-core-modules/ui/frame/frame';
import { ContentView } from 'tns-core-modules/ui/content-view/content-view';
import { TextField } from 'tns-core-modules/ui/text-field';
import { Page } from 'tns-core-modules/ui/page/page';
run({
create: () => {
const frame = new Frame();
frame.navigate({
create: () => {
const page = new Page();
page.backgroundColor = "green";
const contentView = new ContentView();
const textField = new TextField();
contentView.height = 100;
contentView.width = 100;
contentView.backgroundColor = "purple";
textField.text = "Hello, world!";
contentView.content = textField;
page.content = contentView;
return page;
}
});
return frame;
}
});
You don't have to wait for launch event, you could set the root frame in run method itself.
In your code, you were creating the frame but never adding it to root UI element or mark the frame itself as root element
It's recommended to use .content to add child for a ContentView / Page as they are originally designed to hold one child element only.
Use TextField / TextView for input text, TextBase is just a base class.
It seems to me that you try to overcomplicate. You can replace XML with code just by implementing createPage method - Create a page via code.
I just modified default NS + TypeScript Playground template to operate without XML - NS + TypeScript template without XML.
I think you can't leave run as empty as it is expecting an entry to start the app. From {NS} website,
You can use this file to perform app-level initializations, but the
primary purpose of the file is to pass control to the app's root
module. To do this, you need to call the application.run() method and
pass a NavigationEntry with the desired moduleName as the path to the
root module relative to your /app folder.
if you look for run code in "tns-core-modules/application"
function run(entry) {
createRootFrame.value = false;
start(entry);
}
exports.run = run;
and
function start(entry) {
if (started) {
throw new Error("Application is already started.");
}
started = true;
mainEntry = typeof entry === "string" ? { moduleName: entry } : entry;
if (!androidApp.nativeApp) {
var nativeApp = getNativeApplication();
androidApp.init(nativeApp);
}
}
I want to integrate a custom NS core / third party component into an Angular template. The attributes of my component should also be set in the template.
Given the generated sample from tns, i have done the following steps:
Register my Component:
registerElement("TestView", () => require("./test-view").TestView);
Create Component:
import observable = require("data/observable");
import stackLayout = require("ui/layouts/stack-layout");
import label = require("ui/label");
import button = require("ui/button");
import { View } from "ui/core/view";
import { Property, PropertyChangeData, PropertyMetadata, PropertyMetadataSettings } from "ui/core/dependency-observable";
export class TestView extends stackLayout.StackLayout {
public static userNameProperty = new Property(
"userName",
"TestView",
new PropertyMetadata("", PropertyMetadataSettings.None)
);
public get userName(): string {
return this._getValue(TestView.userNameProperty);
}
public set userName(newName: string) {
this._setValue(TestView.userNameProperty, newName);
}
constructor() {
super();
var counter: number = 0;
var lbl = new label.Label();
var btn = new button.Button();
btn.text = "Tap me " + this.userName + "!";
btn.on(button.Button.tapEvent, (args: observable.EventData) => {
lbl.text = "Tap " + counter++;
});
this.addChild(lbl);
this.addChild(btn);
}
}
Use it in Angular template:
<StackLayout class="p-20">
<TestView userName="Felix"></TestView>
</StackLayout>
The component displays, but the button text does not show "Tap me [userName]", because userName is undefined.
What is the correct way to pass arguments as attributes for the component?
Update
Having read Data Binding and Properties, i augmented above code sample with definition of a userName property. But its still not set, quite frustrating...
Can anybody give some insight? Many thanks.
Finally got it working.
There has to be established Data Binding between
Angular template and custom Component TestView by encapsulating the property userName in a Property type of the ui/core/dependency-observable module (see above code).
the component and it's button by binding the component's userName source property to the button target text property (you can also set this by a default BindingContext).
var btn = new button.Button();
var buttonBindingOptions = {
expression: "'Tap me ' + userName + '!'",
sourceProperty: "userName",
targetProperty: "text",
twoWay: false
};
btn.bind(buttonBindingOptions, this);
In the parent Appcomponent user can by dynamically set like this:
app.component.ts:
export class AppComponent {
user : string;
constructor() {
this.user = "Felix";
setTimeout(()=> {this.user = "Other"}, 1000);
}
}
app.html:
<TestView [userName]="user"></TestView>
When I use AIR to invoke cmd.exe, it doesn't show up, but it appears in Task-Manager. When I pass parameter to cmd.exe, it doesn't react. The code has no problem with invoking notepad.exe or wscript.exe.(There is a button named btn on the stage) Here is my code:
import flash.desktop.NativeProcess;
import flash.desktop.NativeProcessStartupInfo;
import flash.filesystem.File;
btn.addEventListener(MouseEvent.CLICK, invokeCmd);
function invokeCmd(e:MouseEvent):void{
if(NativeProcess.isSupported){
btn.label="NativeProcess supported";
var info:NativeProcessStartupInfo = new NativeProcessStartupInfo();
info.executable = new File("C:/Windows/System32/cmd.exe");
var processArg:Vector.<String> = new Vector.<String>();
processArg.push("start dir");
info.arguments = processArg;
var process:NativeProcess = new NativeProcess();
process.start(info);
}
}