When using a custom component for a topBar button, press events are not sent to subscribers.
navigationButtonPressed
function in modal componentExample:
Pushing modal with custom left top button:
Navigation.showModal({
stack: {
children: [{
component: {
name: 'navigation.main.AddToListModal',
options: {
topBar: {
leftButtons: {
id: 'backButton',
component: {
name: 'navigation.topBar.ChevronLeft',
passProps: {
color: 'white'
}
}
},
visible: true
}
}
}
}]
}
})
The modal:
class AddToListModal extends React.PureComponent<Props> {
constructor(props: Props) {
super(props);
Navigation.events().bindComponent(this)
}
navigationButtonPressed({buttonId}) {
if (buttonId == 'backButton') {
Navigation.dismissModal(this.props.componentId);
}
}
render() {
return (
<View>
<Text>Hey</Text>
</View>
);
}
}
The custom top bar component
class IconWrapper extends React.PureComponent {
render() {
return <Icon name='rowing' color={this.props.color || 'black'}/>
}
}
yea it won't listen to custom component, you need to
leftButtons: {
id: 'backButton',
component: {
name: 'navigation.topBar.ChevronLeft',
passProps: {
color: 'white',
// pass event here
onClick: () => this.onLeftButtonClick()
}
}
},
inside your component just call this function on press
I see. I think this is still somewhat problematic since I'm unable to reference the component backing the modal (I think this
in your example would bind to the component _launching_ the modal).
In other words, the left button on the topBar in the modal I'm launching needs to either have a reference to the modal's componentId
or the modal's component itself so that the left button can dismiss the modal. In the example you provided, is there a way to get a reference to the newly popped modal so that the custom component can dismiss it?
@chrisbenincasa yea, normally when you want to call that function inside your button component,
you can define a function inside the button class which will save the current component but you need a reference to the button, such that
inside the button class
componentWillMount() {
this.props.passRef(this)
}
setCurrentComponentId(id) {
this.setState({
currentComponentId: id
})
}
inside the parent view controller
....
_leftButtonRef
....
leftButtons: {
id: 'backButton',
component: {
name: 'navigation.topBar.ChevronLeft',
passProps: {
color: 'white',
// pass event here
passRef: (ref) => this._leftButtonRef = ref
}
}
}
To get this to work I had to do something slightly more complex based on your example. The parent screen had to act as the communicator between the modal and the top button, since neither the parent view nor the top button is able to know about the modal's assigned componentId.
It ended up looking roughly like this:
var modalComponentId: string;
Navigation.showModal({
stack: {
children: [{
component: {
name: 'navigation.main.AddToListModel',
passProps: {
setRef: (cid: any) => modalComponentId = cid
},
options: {
topBar: {
leftButtons: [{
id: 'backButton',
component: {
name: 'navigation.topBar.ChevronLeft',
passProps: {
text: 'Back',
getModalRef: () => modalComponentId
}
}
}],
rightButtons: [{
id: 'doneButton',
text: 'Done',
enabled: false
}],
visible: true
}
}
}
}]
}
})
And then in modal component:
class AddToListModal extends React.PureComponent<Props> {
componentWillMount() {
this.props.setRef(this.props.componentId)
}
render() {
return (
<View></View>
);
}
}
And lastly in the button component:
export default class ModalHeaderButton extends React.PureComponent {
handlePress() {
Navigation.dismissModal(this.props.getModalRef());
}
render() {
return (
<View></View>
);
}
}
Of course, this isn't really ideal, but it works. Hopefully there will be a cleaner way to achieve this at some point!
I fixed it by listening to any event in the navigator using:
this.navigator.setOnNavigatorEvent(this.onNavigatorEvent);
````
and then you just check for:
```javascript
if (event.type === 'NavBarButtonPress')
Here you have a bigger part of the code:
class NavEventsManager {
/**
* This method configure the Navigation Events Manager so it will start capture events.
* @param navigator
*/
init(navigator) {
this.navigator = navigator;
this.navigator.setOnNavigatorEvent(this.onNavigatorEvent);
}
/**
* Navigation event handler.
* @param event
*/
onNavigatorEvent = (event) => {
switch (event.type) {
case 'DeepLink':
this.manageDeepLinks(event);
break;
case 'ScreenChangedEvent':
this.manageScreenChanged(event);
break;
case 'NavBarButtonPress':
this.manageNavBarButtonPress(event);
break;
default:
break;
}
};
manageNavBarButtonPress = (event) => {
this.Log.info('button press with ID:'.concat(event.id));
};
.
.
.
}
Also I fixed with this the screen redirection through the navigation drawer using Deep Links.
@Cicko but your solution looks like a v1 solution. Correct?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.
The issue has been closed for inactivity.
Most helpful comment
@Cicko but your solution looks like a v1 solution. Correct?