Browse Source

fix: prevent closing parent modal on picker modal close (#611)

* fix: modal in modal issue

* chore: fix xcode warnings

* refactor open/close modal logic
master
Henning Hall 2 years ago
committed by GitHub
parent
commit
b8855aca87
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 42 deletions
  1. +5
    -5
      ios/RNDatePicker/RNDatePickerManager.m
  2. +24
    -17
      src/DatePickerAndroid.js
  3. +23
    -20
      src/DatePickerIOS.js
  4. +16
    -0
      src/modal.js

+ 5
- 5
ios/RNDatePicker/RNDatePickerManager.m View File

@ -156,11 +156,11 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *) props
}
// Finding the top view controller which is neccessary to be able to show the picker from within modal
_topViewController = rootViewController;
while (_topViewController.presentedViewController){
_topViewController = _topViewController.presentedViewController;
self->_topViewController = rootViewController;
while (self->_topViewController.presentedViewController){
self->_topViewController = self->_topViewController.presentedViewController;
}
[_topViewController presentViewController:alertController animated:YES completion:nil];
[self->_topViewController presentViewController:alertController animated:YES completion:nil];
});
}
@ -168,7 +168,7 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *) props
RCT_EXPORT_METHOD(closePicker)
{
dispatch_async(dispatch_get_main_queue(), ^{
[_topViewController dismissViewControllerAnimated:YES completion:nil];
[self->_topViewController dismissViewControllerAnimated:YES completion:nil];
});
}

+ 24
- 17
src/DatePickerAndroid.js View File

@ -1,5 +1,6 @@
import React from 'react'
import { requireNativeComponent, NativeModules } from 'react-native'
import { NativeModules, requireNativeComponent } from 'react-native'
import { shouldCloseModal, shouldOpenModal } from './modal'
function addMinutes(date, minutesToAdd) {
return new Date(date.valueOf() + minutesToAdd * 60 * 1000)
@ -18,27 +19,27 @@ const defaultWidth = 310
class DatePickerAndroid extends React.PureComponent {
render() {
const props = this.getProps()
const isClosed = this._isCurrentlyClosed();
this.previousProps = props;
if (props.modal) {
if (props.open && isClosed) {
NativeModules.RNDatePicker.openPicker(
props,
this._onConfirm,
this.props.onCancel
)
} else if (!props.open && !isClosed) {
NativeModules.RNDatePicker.closePicker()
}
return null
if (shouldOpenModal(props, this.previousProps)) {
this.isClosing = false
NativeModules.RNDatePicker.openPicker(
props,
this._onConfirm,
this._onCancel
)
}
if (shouldCloseModal(props, this.previousProps, this.isClosing)) {
this.closing = true
NativeModules.RNDatePicker.closePicker()
}
this.previousProps = props
if (props.modal) return null
return <NativeDatePicker {...props} onChange={this._onChange} />
}
_isCurrentlyClosed = () => !this.previousProps || !this.previousProps.open
getProps = () => ({
...this.props,
date: this._date(),
@ -85,8 +86,14 @@ class DatePickerAndroid extends React.PureComponent {
}
_onConfirm = (isoDate) => {
this.isClosing = true
this.props.onConfirm(this._fromIsoWithTimeZoneOffset(isoDate))
}
_onCancel = () => {
this.isClosing = true
this.props.onCancel()
}
}
export default DatePickerAndroid

+ 23
- 20
src/DatePickerIOS.js View File

@ -1,9 +1,6 @@
import React from 'react'
import {
StyleSheet,
requireNativeComponent,
NativeModules,
} from 'react-native'
import { StyleSheet, requireNativeComponent, NativeModules } from 'react-native'
import { shouldCloseModal, shouldOpenModal } from './modal'
const RCTDatePickerIOS = requireNativeComponent('RNDatePicker')
@ -40,27 +37,35 @@ export default class DatePickerIOS extends React.Component {
}
_onConfirm = ({ timestamp }) => {
this.isClosing = true
this.props.onConfirm(new Date(timestamp))
}
_onCancel = () => {
this.isClosing = true
this.props.onCancel()
}
render() {
const props = this._toIosProps(this.props)
const isClosed = this._isCurrentlyClosed();
this.previousProps = props;
if (props.modal) {
if (props.open && isClosed) {
NativeModules.RNDatePickerManager.openPicker(
props,
this._onConfirm,
props.onCancel
)
} else if (!props.open && !isClosed) {
NativeModules.RNDatePickerManager.closePicker()
}
return null
if (shouldOpenModal(props, this.previousProps)) {
this.isClosing = false
NativeModules.RNDatePickerManager.openPicker(
props,
this._onConfirm,
this._onCancel
)
}
if (shouldCloseModal(props, this.previousProps, this.isClosing)) {
this.isClosing = true
NativeModules.RNDatePickerManager.closePicker()
}
this.previousProps = props
if (props.modal) return null
return (
<RCTDatePickerIOS
key={props.textColor} // preventing "Today" string keep old text color when text color changes
@ -74,8 +79,6 @@ export default class DatePickerIOS extends React.Component {
/>
)
}
_isCurrentlyClosed = () => !this.previousProps || !this.previousProps.open
}
const styles = StyleSheet.create({

+ 16
- 0
src/modal.js View File

@ -0,0 +1,16 @@
export const shouldOpenModal = (props, prevProps) => {
if (!props.modal) return false
if (!props.open) return false
const currentlyOpen = prevProps?.open
if (currentlyOpen) return false
return true
}
export const shouldCloseModal = (props, prevProps, isClosing) => {
if (!props.modal) return false
if (props.open) return false
const currentlyOpen = prevProps?.open
if (!currentlyOpen) return false
if (isClosing) return false
return true
}

Loading…
Cancel
Save