I'm new in NativeScript.
I can't remove the zoom button from webView. Usually, I didn't find any way of resolving this problem.
<Page id="webViewID" class="page" #loaded="onWebViewLoaded($event)">
export default {
methods: {
onWebViewLoaded(event) {
console.log("Hi can I hendle to event for remove zoom");
}
}
}
You can not do it on as in your case. You need to have #loadFinished on webview
<WebView src="url"
#loadFinished="finished"
/>
and in your methods
methods: {
finished(args) {
args.object.android.getSettings().setBuiltInZoomControls(false);
}
}
Related
I am using AWS Amplify in my React Native app as instructed here: https://docs.amplify.aws/ui/auth/authenticator/q/framework/react-native/#using-the-authenticator-component
It is working, more or less. But when I log in there is a box saying Hello with a Sign Out button added to the project. I can get rid of this by setting hideDefault={true} but then if I log out there is no login/signup screen. My code is below, thank you for any help.
import { StyleSheet, Text, Button,View,Platform,StatusBar,Image, TouchableWithoutFeedback, SafeAreaView } from 'react-native';
import {useState} from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { useNavigationContainerRef } from '#react-navigation/native';
import Ionicons from 'react-native-vector-icons/Ionicons';
// Screens
import Browsescreen from './screens/Browsescreen';
// AWS
import { Authenticator } from 'aws-amplify-react-native/dist/Auth';
const Tab = createBottomTabNavigator();
function App() {
const navigationRef = useNavigationContainerRef();
const [showLoggedInPage, setLoggedInPage] = useState(false);
const loggedInPage = showLoggedInPage ? (
<SafeAreaView style={styles.container}>
<StatusBar style="auto" />
<View>
[REMOVED]
</View>
<NavigationContainer ref={navigationRef}>
<Tab.Navigator>
[REMOVED]
</Tab.Navigator>
</NavigationContainer>
</SafeAreaView>
) : null;
return (
<Authenticator
onStateChange={(authState) => {
console.log(authState)
if (authState == "signedIn") {
setLoggedInPage(true);
} else {
setLoggedInPage(false);
}
}
}
hideDefault={false}
>
{loggedInPage}
</Authenticator>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ddd',
},
});
export default App;
I am new to this, please make it as simple as possible and provide sample if possible. Thank you!
Based on this documentation, if you are using the HOC component withAuthenticator.
export default withAuthenticator(App, {
// Render a sign out button once logged in
includeGreetings: true,
});
The sign-out button is shown when "includeGreetings" is set to "true". Changing it to "false" will hide the sign-out button.
I have this code that show the tabBadge number
<ion-tabs selectedIndex="{{activeTab}}">
<ion-tab [root]="tabThongBaoPage" tabIcon="notifications" [tabBadge]="badge.getBadge()" tabBadgeStyle="danger"></ion-tab>
</ion-tabs>
and the service controller the bag number
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/toPromise';
import CONST from '../variable';
#Injectable()
export class BadgeSinhService {
badge: number = 0;
constructor() {
}
getBadge(): number {
return this.badge;
}
setBadge(badge): number {
this.badge = badge;
return this.badge;
}
incrementBadge() {
this.badge++
return
}
decreaseBadge() {
if (this.badge > 0) {
this.badge--
}
return;
}
}
If I click on the button with event like this
<button ion-button (click)="cong()">Cong</button>
<button ion-button (click)="tru()">Tru</button>
cong() {
this.badge.incrementBadge()
}
tru() {
this.badge.decreaseBadge()
}
The tabBadge number updated on the view, as soon as the button is click and the click event is fire
But I also have this code that wait for notification event, that will be fire when the server send a notification to the app, it will increment the tab badge number
push.on('notification', (data) => {
console.log('notifi updatei');
this.badge.incrementBadge();
})
It does increment the tab badge number but the view is not update, only when I tap on the tab then the badge number will update on the view
Why it not update the view like the click event ?
I found the answer,use ngZone to notifi angular2 to update the view
push.on('notification', (data) => {
console.log('notifi updatei');
this.badge.incrementBadge();
})
somehow the code above not create a async task in angular 2 zone, maybe because push.on not belong to angular 2
but the answer is
this.zone.run(() => {
// increment badge
})
My template:
<ion-item-sliding *ngFor="let draft of drafts">
<ion-item>
<h2>Report draft header</h2>
</ion-item>
<ion-item-options side="left">
<button ion-button color="secondary" (click)="draftUpload(draft.report.pk)">
<ion-icon name="md-cloud-upload"></ion-icon>
Upload
</button>
</ion-item-options>
</ion-item-sliding>
In the controller, I do this:
draftUpload(pk) {
this.dataService.uploadReport(pk);
this.drafts = this.dataService.getDraftReports();
}
Here is the getDraftReports() functions:
getDraftReports() {
var draftReports = [];
let reportObj : any;
this.storage.forEach((value, key, index) => {
reportObj = JSON.parse(value);
if(reportObj.report.uploaded=="no"){
draftReports.push(reportObj);
}
});
return draftReports;
}
This doesn't work, although the DB changes are made. If I refresh the page, or navigate away and back, the list updates.
What am I doing wrong?
It seems a change detection issue. Change detection is fired on every browser event, timeout or http request.
The case is that your function: getDraftReports() is asyncronous and is its callback is not detected for Angular and consequently it doesn't fires the change detection event in order to update the view.
In order to solve this you will have to wrap this function into the angular zone. See this code:
import zone:
import { NgZone } from '#angular/core';
Inject the service ngZone:
constructor(private zone: NgZone) {
....
}
And finally add this to your function:
draftUpload(pk) {
this.dataService.uploadReport(pk);
this.zone.run(
() => {
this.drafts = this.dataService.getDraftReports();
}
)
}
Hope this helps.
this.storage.foreach returns a promise and hence is asynchronous.
Your draftReports array is returned before it is set.You need to return the promise :
getDraftReports(draftsHandler:any) {
//var draftReports = [];
//Use a filter method and return the promise.
return this.storage.forEach((value, key, index) => {
let reportObj : any;
reportObj = JSON.parse(value);
if(reportObj.report.uploaded=="no"){
//draftReports.push(reportObj);
draftsHandler(reportObj);
}
});
}
In your draftUpload set drafts within then.
draftUpload(pk) {
this.dataService.uploadReport(pk);
this.dataService.getDraftReports((data)=>this.draftsHandler(data)).then(()=>{
//next steps
}
}
draftsHandler(data:any){
this.drafts.push(data)
}
I am building a 'Watch this deal' functionality, which is similar to FB 'like' feature. (Ember version 1.13)
Here is the scenario:
There is an icon beside every deal which will enable the current user to 'watch' or 'not watch' the deal. The actions are completed and working and changes on the UI is also working fine. The problem is, when I click on that icon, I become a watcher of the deal but the icon doesn't change. I have to refresh the page to see that change.
controller:
actions:{
// add and remove watchers
addToWatcher: function(deal) {
var _this = this;
var currentUser = this.get('currentUser');
deal.get('watchers').addObject(currentUser);
deal.save().then(function () {
Ember.get(_this, 'flashMessages').success("You are now watching");
}, function() {
// Ember.get(_this, 'flashMessages').danger('apiFailure');
});
},
removeWatcher: function(deal) {
var _this = this;
var currentUser = this.get('currentUser');
deal.get('watchers').removeObject(currentUser);
deal.save().then(function () {
Ember.get(_this, 'flashMessages').success("You are now watching");
}, function() {
// Ember.get(_this, 'flashMessages').danger('apiFailure');
});
}
}
templates:
{{#if (check-watcher deal currentUser.id)}}
<i class="fa fa-2x sc-icon-watch watched" {{action 'removeWatcher' deal}} style="padding: 5px 10px;"></i><br>
{{else}}
<i class="fa fa-2x sc-icon-watch" {{action 'addToWatcher' deal}} style="padding: 5px 10px;"></i><br>
{{/if}}
Here check-watcher is a helper I wrote to check if the deal is being watched by the current user. If it is, the icon will be Red and clicking on it again will trigger 'removeWatcher' action. If not, icon will be black and clicking on it will make user watch the deal.
check-watcher helper:
import Ember from 'ember';
export function checkWatcher(object, currentUser) {
var currentUser = object[1];
var watchers = object[0].get('watchers').getEach('id');
if (watchers.contains(currentUser)) {
return true;
} else{
return false;
}
}
export default Ember.Helper.helper(checkWatcher);
If I were to just change the class, that would have been easy, but I have to change the action too in the views, that's where it's a little tricky.
So, how to make the change in UI happen between adding and removing watchers without refreshing the page?
In short, you need to define a compute method for the helper:
import Ember from 'ember';
export function checkWatcher(object, currentUser) {
var currentUser = object[1];
var watchers = object[0].get('watchers').getEach('id');
if (watchers.contains(currentUser)) {
return true;
} else{
return false;
}
}
export default Ember.Helper.extend({ compute: checkWatcher });
In that case, the helper will recompute its output every time the input changes.
And there is not need to change an action in a template. You could always call 'toggleWatcher' action from template, and then decide what to do in the controller:
toggleWatcher(deal) {
var currentUser = this.get('currentUser');
if (deal.get('watchers').contains(currentUser)) {
this.send('removeWatcher', deal);
} else {
this.send('addToWatcher', deal);
}
}
I'm right now creating my app only in C++, i creating the NavigationPane and adding the container with the Views i need. It works fine, but i want to capture a Button clicked to make the NavigationPane pop the current page and push a diferent (made in runtime) Page.
How can it be achieved, i tried working with the signals, but i think i'm not getting how it works the signals and the QT_SLOTS, in the case of the NavigationPane, it doesn't have those methods as QT_SLOT.
Any advice will be appreciated.
You first need to connect the clicked() signal of your Button to the pop() slot of your NavigationPane. It should look like this:
// Connect the button's clicked() signal to the navigation pane's
// pop() slot.
bool connectResult = QObject::connect(myButton,
SIGNAL(clicked()),
myPane,
SLOT(pop()));
// Use the Q_ASSERT() function to test the return value and
// generate a warning message if the signal slot connection
// wasn’t successful.
Q_ASSERT(connectResult);
// Indicate that the variable connectResult isn't used in the
// rest of the app to prevent a compiler warning.
Q_UNUSED(connectResult);
This page about buttons might help you understand how to handle this. To better understand how to connect objects together, you might also want to have a look at a the signals and slots documentation.
You then have to create and push your new page after the pop. To do that, you simply have to connect the popTransitionEnded (bb::cascades::Page *page) slot of your NavigationPane to your custom function that will do the job.
bool connectResult = QObject::connect(myPane,
SIGNAL(popTransitionEnded(bb::cascades::Page*)),
this,
SLOT(createNewPageAndPushIt(bb::cascades::Page*)));
Q_ASSERT(connectResult);
Q_UNUSED(connectResult);
See this page for more details about the usage of NavigationPane to stack pages.
---------------------TRY THIS-------------
Get sample app from my github samples for your query....
https://github.com/svmrajesh/BB-10-Cascades/tree/master/MY%20APPS/stackNavigation
main.qml: (first page)
import bb.cascades 1.0
NavigationPane {
id: navigationPane
backButtonsVisible: false
peekEnabled: false
Page
{
id: rootPage
Container {
background: Color.LightGray
layout: DockLayout {
}
Label {
text: "First page"
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
}
}
actions: [
ActionItem {
title: "Next page"
ActionBar.placement: ActionBarPlacement.OnBar
onTriggered: {
var page = pageDefinition.createObject();
navigationPane.push(page);
}
attachedObjects: ComponentDefinition {
id: pageDefinition
source: "PageTwo.qml"
}
}
]
}
onPopTransitionEnded: {
page.destroy();
}
}
2.second page
import bb.cascades 1.0
Page {
id: pageTwo
Container {
background: Color.Gray
layout: DockLayout {
}
Label {
text: "Second page"
horizontalAlignment: HorizontalAlignment.Center
}
Container {
layout: StackLayout {
}
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
Button {
text: qsTr("Next Page")
imageSource: "asset:///images/picture1thumb.png"
onClicked: {
// show detail page when the button is clicked
var page = getSecondPage();
console.debug("pushing detail " + page)
navigationPane.push(page);
}
property Page secondPage
function getSecondPage() {
if (! secondPage) {
secondPage = secondPageDefinition.createObject();
}
return secondPage;
}
attachedObjects: [
ComponentDefinition {
id: secondPageDefinition
source: "PageTwoOne.qml"
}
]
}
Button {
text: "Previous Page"
onClicked: {
navigationPane.pop();
}
}
}
}
/* ------------- Use this Code If back button visibility is "True"-----------------
paneProperties: NavigationPaneProperties {
backButton: ActionItem {
title: "Back"
// imageSource: "asset:///back.png"
onTriggered: {
navigationPane.pop();
}
}
} */
}
3.last page
import bb.cascades 1.0
Page {
id: pageTwoone
Container {
background: Color.DarkGray
layout: DockLayout {}
Label {
horizontalAlignment: HorizontalAlignment.Center
text: "Last Page"
}
Container {
layout: StackLayout {}
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
Button {
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
text: qsTr("Goto Home Page")
onClicked: {
// show detail page when the button is clicked
navigationPane.navigateTo(rootPage);
}
}
Button {
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
text: qsTr("Goto Back")
onClicked: {
// show detail page when the button is clicked
navigationPane.pop();
}
}
}
}
}
------------ ADD More pages to navigate using this code----------------------------
-------------copy this code and run.. get sample app from above link if needed ------
Have you checked this?
https://developer.blackberry.com/native/reference/cascades/bb__cascades__navigationpane.html
NavigationPane* navigationPane; // Global var to change current Page with push/pop
void initializeNavigationPane()
{
ActionItem* nextAction = ActionItem::create()
.title("Next page")
.onTriggered(this, SLOT(pushPage()));
navigationPane = NavigationPane::create();
QObject::connect(navigationPane, SIGNAL(popTransitionEnded(bb::cascades::Page*)),
this, SLOT(popFinished(bb::cascades::Page*)));
// Put a new page
navigationPane->push(Page::create()
.content(Label::create("First page"))
.addAction(nextAction, ActionBarPlacement::OnBar));
Application::instance()->setScene(navigationPane);
}
void popFinished(bb::cascades::Page* page){
delete page;
}
//You have to connect this method when you want a new Page pushed.
Q_SLOT void pushPage(){
ActionItem* backAction = ActionItem::create()
.title("Previous page")
.imageSource(QUrl("asset:///back.png"))
.onTriggered(navigationPane, SLOT(pop()));
navigationPane->push(Page::create()
.content(Label::create("Second page"))
.paneProperties(NavigationPaneProperties::create()
.backButton(backAction)));
}
Explication:
An instance of the object NavigationPane allows change the current page to others with the push/pop effect (see image):
developer.blackberry.com/native/files/reference/cascades/images/navigation_pane_push_pop.png
You have to inicialice with:
navigationPane = NavigationPane::create();
And tell to the Application you will use this instance to change page:
Application::instance()->setScene(navigationPane);
Now you app got a NavigationPane, but nothing is inside, if you run it, you will get a black screen, to add a page (the principal page - page0) use push:
navigationPane->push(Page::create()
.content(Label::create("First page")));
To add a new Page that It can go back to the page0 we just push use Push again, Remeber include the back button to go back:
navigationPane->push(Page::create()
.content(Label::create("Second page"))
.paneProperties(NavigationPaneProperties::create()
.backButton(ActionItem::create()
.title("Previous page")
.imageSource(QUrl("asset:///back.png")) //You should add manually this image.
.onTriggered(navigationPane, SLOT(pop()))));
Q_INVOKABLE void insert (intindex, bb::cascades::Page *page )
https://developer.blackberry.com/native/reference/cascades/bb__cascades__NavigationPane.html#function-insert-index-page
Inserts a page at a specified index in the NavigationPane.
The page that is passed must not be 0 or it will be ignored. If the
page is already present in the navigation stack, the operation will
fail. This operation will not trigger a transition effect, even if the
page is added to the top of the stack. If a transition effect is
desired, use push() instead. The topChanged() signal will be emitted
if the operation affects the top node.
Parameters
1- index
The index where the page will be placed. If the index < 0 the the page is inserted in the bottom. If the index > the number of pages in the navigation stack, it is added on top of the stack.
2- page
The page to be inserted, must not be 0.
Since: BlackBerry 10.0.0
An idea is
You could use:
navigationPane.count() To get the current pages in the nagationPane stack, and use:
navigationPane.insert(navigationPane.count()-1, myPageToBeBack); To push a page between the current page and
the previous one