I have a nested tabNavigator inside of another tabNavigator, and I'm trying to get the inner tabNavigator's tabBar to be hidden. (The one below that shows "Map" and "list"). I'd like to keep the main tabNavigator which reads "Map Favorites Add a Site More".
The code which is rendering it this way is below:
const MainNavigator = StackNavigator({
login: {
screen: LoginScreen
},
main: {
screen: TabNavigator({
search: {
screen: TabNavigator({
map: {
screen: MapScreen
},
list: {
screen: ListScreen
}
})
},
favorites: {screen: FavoritesScreen},
addSite: {screen: AddSiteScreen},
more: {screen: MoreScreen}
})
},
filter: {
screen: FilterScreen,
navigationOptions: {
tabBarVisible: false
}
}
}, {
lazy: true
});
I've tried adding
navigationOptions: {
tabBarVisible: false
}
to the search item as shown below:
search: {
screen: TabNavigator({
map: {
screen: MapScreen
},
list: {
screen: ListScreen
}
},
navigationOptions: {
tabBarVisible: false
})
}
but it ends up hiding the outermost TabNavigator (the one which reads "Map Favorites Add a Site More") instead of the inner one as I'd expect. (Image below)
Finally, out of ideas and thinking maybe it needs to be nested in as far as possible, I've also tried adding the
navigationOptions: {
tabBarVisible: false
}
to the innermost map and list items as such:
search: {
screen: TabNavigator({
map: {
screen: MapScreen,
navigationOptions: {
tabBarVisible: false
}
},
list: {
screen: ListScreen,
navigationOptions: {
tabBarVisible: false
}
}
})
}
but the result of this is hiding both of the TabNavigators and there are none at all. Am I missing something simple on how to achieve this?
Thanks
You are correct in adding the navigationOptions with a property of tabBarVisible: false. However, you want to add it as a property to the tabNavigator, not to the screen itself like so:
search: {
screen: TabNavigator({
map: {
screen: MapScreen,
navigationOptions: {
tabBarVisible: false
}
},
list: {
screen: ListScreen
}
}, navigationOptions: {
tabBarVisible: false
});
}
One thing I want to point out is that lazy: true was deprecated in react-navigation version 23, so unless you are on version 22 or below that won't do anything.
I never ended up finding a good answer to this question, and it seems like it might be a limitation of the library.
As a workaround (which works just as well), I decided instead of having three distinct screens: SearchScreen, MapScreen, and ListScreen, I just went down to only having one screen SearchScreen, and when that screen renders, it calls a component to render inside of it.
The navigation portion is now much flatter and looks like this:
main: {
screen: TabNavigator({
search: {screen: SearchScreen},
favorites: {screen: FavoritesScreen},
addSite: {screen: AddSiteScreen},
more: {screen: MoreScreen}
})
}
Then inside of the SearchScreen, I just render the components (instead of treating them as their own distinct screens)
renderSearchScreen = () => {
const {viewStyle, lastKnownRegion, mapLoaded, sites} = this.props;
if (viewStyle === map.SearchOptions.MAP) {
return (
<SearchMap
lastKnownRegion={lastKnownRegion}
mapLoaded={mapLoaded}
updateRegion={this.props.updateRegion}
sites={sites}
/>
);
} else {
return (
<SearchList
sites={sites}
/>
);
}
};
After these changes, it's worked fine with no issues. I suppose it's also cleaner, and more logical from an architecture standpoint that Map and List be components that are nested and rendered instead of them also being distinct screens.
Hopefully this can help anyone else who runs into a similar issue with nested TabNavigators!
Related
I want to add new Icon for images I add on canvas, just like mentioned in following post:
Add remove icon on image in canvas HTML5 and Fabric js
$('#remove').on('click', function(){
canvas.getActiveObject().remove();
});
canvas.on('object:selected', function(o) {
if (o.target.isType('image')) {
$('#remove').show();
}
});
canvas.on('selection:cleared', function() {
$('#remove').hide();
});
But, this solution can not work for me. I want to achieve something like done in following code:
http://jsfiddle.net/tornado1979/0fbefh52/6/
Here, I want to display any custom Image based on my code conditions.
Is there any way to achieve this.
Thanks
Thanks #Durga,
The link https://github.com/pixolith/fabricjs-customise-controls-extension has solved my problem.
Following is the way to customise the control options:
fabric.Canvas.prototype.customiseControls({
tl: {
action: 'rotate',
cursor: 'cow.png'
},
tr: {
action: 'scale'
},
bl: {
action: 'remove',
cursor: 'pointer'
},
br: {
action: 'moveUp',
cursor: 'pointer'
},
mb: {
action: 'moveDown',
cursor: 'pointer'
},
mt: {
action: {
'rotateByDegrees': 45
}
},
mr: {
action: function( e, target ) {
target.set( {
left: 200
} );
canvas.renderAll();
}
},
// only is hasRotatingPoint is not set to false
mtr: {
action: 'rotate',
cursor: 'cow.png'
},
}, function() {
canvas.renderAll();
} );
I have two StackNavigator. Movies:
const MoviesStackNavigator = createStackNavigator({
Movies: Movies,
MovieDetails: MovieDetails,
},{
initialRouteName: 'Movies',
})
and actors:
const ActorsStackNavigator = createStackNavigator({
Actors: Actors,
ActorDetails: ActorDetails,
},{
initialRouteName: 'Actors',
})
I am using them inside a TabNavigator:
const RootTabs = createBottomTabNavigator({
Movies: {
screen: MoviesStackNavigator,
navigationOptions: {
tabBarLabel: 'Movies'
}
},
Actors: {
screen: ActorsStackNavigator,
navigationOptions: {
tabBarLabel: 'Actors'
}
},
})
When the user changes tab, I want him to arrive to the root component of that tab (Movies or Actors), not to a stacked component (MoviesDetails or ActorsDetails). In other word, when a user quits a tab, the StackNavigator in that tab should be resetted to the root component.
My first approach was to use StackActions.reset when initializing the root component in a tab to try to reset the other tab (that the user just quit) but the library prevents interacting between navigators, at least in that way.
So, any ideas?
My solution was to use tabBarOnPress:
const RootTabs = createBottomTabNavigator({
Movies: {
screen: MoviesStackNavigator,
navigationOptions: {
tabBarLabel: 'Movies',
tabBarOnPress: ({navigation, defaultHandler}: any) => {
navigation.navigate('Actors')
defaultHandler()
},
}
},
Actors: {
screen: ActorsStackNavigator,
navigationOptions: {
tabBarLabel: 'Actors',
tabBarOnPress: ({navigation, defaultHandler}: any) => {
navigation.navigate('Movies')
defaultHandler()
},
}
},
})
I am creating a tree with kendo treeView like this:
const treeViewOptions: kendo.ui.TreeViewOptions = {
dataBound: (e: kendo.ui.TreeViewDataBoundEvent): void => {
// Add class to the treeItem that is a folder to distiguish between leaf and folder.
const treeItem = $(this.treeViewElementId + ' .k-item:has(.k-group)');
if (treeItem.length > 0) {
treeItem.addClass("folder-tree-item");
}
},
dataSource: new kendo.data.HierarchicalDataSource({
sort: { field: "text", dir: "asc" },
transport: {
read: (options: kendo.data.DataSourceTransportOptions) => { this.onLoadFolder(options); }
},
schema: {
model: {
id: "id",
},
}
}),
dataSpriteCssClassField: "iconClass",
template:
// Text - I have a template here.
// Make all nodes load automatically before expanding
loadOnDemand: false,
// Apply scrolling when item focus changes
navigate: (e) => { this.onNavigate(e); },}
When I expand or collapse a node this is take a lot of time until the folder is open / close..
What should I do?
Thanks
The solution to this was already discussed in another question, basically you need to either update kendo ui or follow the steps given in the answer to the question.
Hope this helps you :)
I cannot seem to figure out how to smoothly animate back to the originator of a hero animation. By that I mean, I have paper-card with a bunch of html (img, text, ect) on it, which I can "hero" into another element fine; but I'd like to be able to "anti-hero" back to the (much smaller) paper-card smoothly. My attempts only produce very distorted backwards transitions. The effect I'm trying to imitate is from Google's 2015 IO under the "Featured Sections". Google displays a grid of thumbnails, that when clicked, hero into youtube videos. Pressing the back arrow anti-heros back to the Featured Sections grid...smoothly. Any thoughts?
I'm sorry for the code blocks, I don't have enough reputation to display something.
My animationConfig is
animationConfig: {
value: function() {
return {
'entry': [{
name: 'cascaded-animation',
animation: 'scale-up-animation'
},
{
name: 'hero-animation',
id: 'hero',
toPage: this
}],
'exit': [{
name: 'cascaded-animation',
animation: 'scale-down-animation'
},
{
name: 'hero-animation',
id: 'hero',
fromPage: this
}]
}
}
}
And when a tap event is fired by clicking on an item, I fade out all remaining items and hero the clicked item.
_onItemTap: function(event) {
var nodes = this.$.scrollUp.children;
var nodesToScale = [];
for(var node, index = 0; node = nodes[index]; index++) {
if (node !== event.detail.item) {
nodesToScale.push(node);
}
}
this.animationConfig['entry'][0].nodes = nodesToScale;
this.animationConfig['exit'][0].nodes = nodesToScale;
this.sharedElements = {'hero': event.detail.item};
this.fire('feed-item-tap', {item: event.detail.item, data: event.detail.data});
}
This renders just fine. Element2's innerHTML is faded in upon entry in order to appear more graceful.
animationConfig: {
value: function() {
return {
'entry': [{
name: 'cascaded-animation',
animation: 'fade-in-animation',
nodes: [this.$.bio, this.$.pic],
timing: {delay: 500, duration: 2000}
},
{
name: 'hero-animation',
id: 'hero',
toPage: this
}],
'exit': [{
name: 'hero-animation',
id: 'hero',
fromPage: this
}]
}
}
}
sharedElements: {
value: function() {
return {
'hero': this.$.more_details
}
}
}
Again, the animations do occur both ways, but the hero from element2 back to element1 does not mimic the behavior on Google's IO site.
You are applying two animations on entry with cascading and delay while at the same time playing the hero animation.
Try to make it simpler using the hero animation only. The animation on Google's IO page looks like a simple hero.
Like this:
animationConfig: {
value: function() {
return {
'entry': {
name: 'hero-animation',
id: 'hero',
toPage: this
},
'exit': {
name: 'hero-animation',
id: 'hero',
fromPage: this
}
}
}
},
sharedElements: {
value: function() {
return {
'hero': this.$.more_details
}
}
}
I want to override the image plugin in CKeditor. When I right click on an image I want to open my own dialog. Can anyone point me in the right direction. I've done a basic plugin which I copied from the CKeditor site - How do I swap this to replace the image editor.
CKEDITOR.plugins.add('myplugin',
{
init: function (editor) {
editor.addCommand('mydialog', new CKEDITOR.dialogCommand('mydialog'));
if (editor.contextMenu) {
editor.addMenuGroup('mygroup', 10);
editor.addMenuItem('My Dialog',
{
label: 'Open dialog',
command: 'mydialog',
group: 'mygroup'
});
editor.contextMenu.addListener(function (element) {
return { 'My Dialog': CKEDITOR.TRISTATE_OFF };
});
}
CKEDITOR.dialog.add('mydialog', function (api) {
// CKEDITOR.dialog.definition
var dialogDefinition =
{
title: 'Sample dialog',
minWidth: 390,
minHeight: 130,
contents: [
{
id: 'tab1',
label: 'Label',
title: 'Title',
expand: true,
padding: 0,
elements:
[
{
type: 'html',
html: '<p>This is some sample HTML content.</p>'
},
{
type: 'textarea',
id: 'textareaId',
rows: 4,
cols: 40
}
]
}
],
buttons: [CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton],
onOk: function () {
// "this" is now a CKEDITOR.dialog object.
// Accessing dialog elements:
var textareaObj = this.getContentElement('tab1', 'textareaId');
alert("You have entered: " + textareaObj.getValue());
}
};
return dialogDefinition;
});
}
});
Hi the reason I wanted to do this was that we have our image editor control which for "usability" reasons we need to carry on using. It gets used in different bits of the site and two dialogs would confuse people. In summary what I did was
Remove the image plugin CKEDITOR.config.removePlugins = 'image, forms, div,flash,iframe,table';
Add extra plugins extraPlugins: 'tinsertimage,teditimage,teditlink,tinsertlink,teditimagelink' on creating the CKEditor
In the plugin run some JS which intercept the right click on the image
CKEDITOR.plugins.add('teditimage',
{
init: function (editor) {
editor.addCommand('tEditImage',
{
exec: function (editor) {
//This opens the custom editor
ZWSInlineEditor.openImageProperties(editor, false);
}
});
if (editor.addMenuItem) {
// A group menu is required
// order, as second parameter, is not required
editor.addMenuGroup('gImage');
// Create a manu item
editor.addMenuItem('gEditImageItem', {
label: 'Edit Image Properties',
command: 'tEditImage',
group: 'gImage'
});
}
if (editor.contextMenu) {
editor.contextMenu.addListener(function (element, selection) {
// Get elements parent, strong parent first
var parents = element.getParents("img");
// Check if it's strong
if (parents[0].getName() != "img")
return null; // No item
return { gEditImageItem: CKEDITOR.TRISTATE_ON };
});
}
}
});
I don't understand what's the point in what you're doing (or please explain us). Maybe you should rather customize dialogs than do things from scratch?