react-native-swipeable
react-native-swipeable copied to clipboard
Open onPress
Can I do the opposite of .recenter with an onPress action? For example i want to activate the right content by using onPress action on an icon.
You can use Animated API to activate the right content by using onPress action on an icon.
example:
var pan = this.swipe.state.pan;
pan.flattenOffset();
Animated.timing(pan, {
toValue: { x: -100, y: 0 },
duration: 250
}).start();
Using @reftp740 example, I got it working with this:
<TouchableHighlight
onPress={() => {
let pan = this.swipeable.state.pan;
pan.flattenOffset();
Animated.timing(pan, {
toValue: { x: -100, y: 0 },
duration: 250,
}).start();
}
}>
Click me
</TouchableHighlight>
<Swipeable onRef={ref => (this.swipeable = ref)}>{blah}</Swipeable>
The above code worked for opening it, however if you tried to swipe close the item would have a glitch and close weird because the state didn't match up with what was showing on the screen. I wrote a open
and toggle
function to help with opening an closing the buttons. There's very simple working example below, there's also an expo snack if you want to see it in action
/// @name open
/// @description This will open the left or right buttons
/// @arg {string} side ['right'] - The side to open.
/// @arg {fn} onDone - do something after the buttons are open
Swipeable.prototype.open = function open (side = 'right', onDone) {
const { pan } = this.state
const left = side === 'left'
const right = side === 'right'
this.setState({
leftActionActivated: left,
leftButtonsActivated: left,
rightActionActivated: right,
rightButtonsActivated: right,
}, () => {
const animationFn = this._getReleaseAnimationFn()
const animationConfig = this._getReleaseAnimationConfig()
this.setState({
lastOffset: animationConfig.toValue,
leftActionActivated: false,
leftButtonsActivated: left,
leftButtonsOpen: left,
rightActionActivated: false,
rightButtonsActivated: right,
rightButtonsOpen: right,
})
pan.flattenOffset()
animationFn(pan, animationConfig).start(onDone)
})
}
/// @name toggle
/// @description This will open the left or right buttons
/// @arg {string} side ['right'] - The side to open.
/// @arg {fn} onDone - do something after the buttons are toggled
Swipeable.prototype.toggle = function toggle (side = 'right', onDone) {
if (!this.state[`${side}ButtonsOpen`]) {
this.open(side, onDone)
} else {
this.recenter()
}
}
Working Example
import React, { PureComponent } from 'react'
import { TouchableHighlight, Text } from 'react-native'
import Swipeable from 'react-native-swipeable'
const styles = {
button: {
padding: 10,
backgroundColor: '#1d87e5',
},
}
function Button ({ title, style, ...props } = {}) {
return (
<TouchableHighlight style={[ styles.button, style ]} {...props}>
<Text style={{ color: '#fff' }}>{title}</Text>
</TouchableHighlight>
)
}
class Page extends PureComponent {
render () {
return (
<>
<Button onPress={() => this.swipeable.toggle('right')} title="Toggle Right" />
<Button onPress={() => this.swipeable.toggle('left')} title="Toggle Left" />
<Swipeable
onRef={(ref) => {
this.swipeable = ref
}}
leftButtons={[ <Button style={{ alignItems: 'flex-end' }} title="Learn More" /> ]}
rightButtons={[ <Button title="Learn More" /> ]}
>
<Text>
Lorem ipsum dolor sit amet, consectetur adipisicing elit
</Text>
</Swipeable>
</>
)
}
}
Both of this solution work , but open always the last record and not the one user select.
Can u help on this ? @denis-shvets @jshanson7
Using @reftp740 example, I got it working with this:
<TouchableHighlight onPress={() => { let pan = this.swipeable.state.pan; pan.flattenOffset(); Animated.timing(pan, { toValue: { x: -100, y: 0 }, duration: 250, }).start(); } }> Click me </TouchableHighlight> <Swipeable onRef={ref => (this.swipeable = ref)}>{blah}</Swipeable>
Your solution work , but open always the last record and not the one user select.
Can u help on this ?
From what you're saying it sounds like you're trying to render multiple Swipeables in the same component and you can't set the ref to the same thing (this.swipeable
) otherwise the last Swipeable will be the only one you have access to because it would be the last one to run it's onRef
function. Assuming this is the case you would have to store all the refs
in an array and loop over them. It would look something like this, sorry I don't have the time to do a full working example but this should get you headed in the right direction.
class Page extends PureComponent {
swipeable = []
forEachSwipeable (callback) {
this.swipeables.forEach(callback)
}
renderSwipeable () {
return (
<Swipeable
onRef={(ref) => {
this.swipeables.push(ref)
}}
...
>
...
</Swipeable>
)
}
render () {
return (
<>
...
this.renderSwipeable()
this.renderSwipeable()
</>
)
}
}
Tried this :
The Flatlist is composed by 2 element.
<Swipeable onRef={(ref) => { this.swipeable = ref; this.swipeable_arr.push(ref) }}
<TouchableOpacity onPress={() => this.openSlider(this.swipeable)} ><Text>Click</Text>
openSlider = (item) => {
for (let i = 0; i < this.swipeable_arr.length; i++) {
console.log("Total Size ", this.swipeable_arr.length)
const element = this.swipeable_arr[i];
if (item == element) {
console.log("Equal")
Animated.timing(item.state.pan, {
toValue: { x: -500, y: 0 },
duration: 250,
}).start();
} else {
console.log("Not equal")
}
}
But this will open always the last item ...
This is the log ...
Total Size 2 Not equal Total Size 2 Equal