dancormier / react-native-swipeout Goto Github PK
View Code? Open in Web Editor NEWiOS-style swipeout buttons behind component
License: MIT License
iOS-style swipeout buttons behind component
License: MIT License
Great plugin Dan. When using the example project as is, things are working as expected inside the ListView. However, if I just drop a component real quick inside my react native playground app, just like the example snippet on the code page shows, I'm not seeing the swipeout working correctly.
After taking a closer look at the code, I noticed that _handlePanResponderMove is properly setting the contentpos state to the right value, but inside _handlePanResponderEnd the value returned by this.state.contentpos is always 0 which results in the swipeout buttons not being shown.
I'm failing to see what is different in my setup here that makes this fail consistently when it's obviously working just fine for most people. Could I be missing something?
Detect device rotation and render with newly-established device width. I'll need to look into how to detect rotation gesture from within react-native.
Add a wiki for scroll prop to prevent README.md clutter.
getInitialState: function() {
return { scrollEnabled: true }
}
...
allowScroll: function(scrollEnabled) {
this.setState({ scrollEnabled: scrollEnabled })
}
...
<Swipeout scroll={event => this.allowScroll(event)}>
<View>
...
</View>
</Swipeout>
...
<ListView scrollEnabled={this.state.scrollEnabled}.../>
Current example:
getInitialState: function() {
var ds = new ListView.DataSource({rowHasChanged: (row1, row2) => true})
return {
dataSource: ds.cloneWithRows(rows),
scrollEnabled: true
}
}
, _allowScroll: function(scrollEnabled) {
this.setState({ scrollEnabled: scrollEnabled })
}
, _handleSwipeout: function(sectionID, rowID) {
for (var i = 0; i < rows.length; i++) {
if (i != rowID) rows[i].active = false
else rows[i].active = true
}
this._updateDataSource(rows)
}
, _updateDataSource: function(data) {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(data)
})
}
, _renderRow: function (rowData: string, sectionID: number, rowID: number) {
return <Swipeout
left={rowData.left}
right={rowData.right}
rowID={rowID}
sectionID={sectionID}
autoClose={rowData.autoClose}
backgroundColor={rowData.backgroundColor}
close={!rowData.active}
onOpen={(sectionID, rowID) => this._handleSwipeout(sectionID, rowID)}
scroll={event => this._allowScroll(event)}>
<View style={styles.li}>
<Text style={styles.liText}>{rowData.text}</Text>
</View>
</Swipeout>
}
i wish can close an opened swipe,the way ?
if i swipe a row's button, when i swipe at another row, i hope close other swipe, how ?
@dancormier
I am making a page alike IOS Phone - Favorites when you can swipe left for actions and auto-close the swipeouts when tabbing other components or change tab view
licecap is a great way to capture gifs easily on your screen - it would be useful for people browsing this to get a quick look at how it works π
I am getting an error in xcode that says "Lexical or preprocessor error 'RTCRootView.h' not found."
// open swipeout manually
, _open: function(direction) {
this.refs.swipeoutContent.measure((ox, oy, width, height) => {
this.setState({
btnWidth: (width/5),
btnsLeftWidth: this.props.left ? (width/5)*this.props.left.length : 0,
btnsRightWidth: this.props.right ? (width/5)*this.props.right.length : 0,
contentHeight: height,
contentWidth: width,
});
});
btnsRightWidth = this.state.btnsRightWidth;
btnsLeftWidth = this.state.btnsLeftWidth;
if (direction == 'right') {
// open swipeout right
this._tweenContent('contentPos', -btnsRightWidth);
this.setState({ contentPos: -btnsRightWidth, openedLeft: false, openedRight: true });
} else if (direction == 'left') {
// open swipeout left
this._tweenContent('contentPos', btnsLeftWidth);
this.setState({ contentPos: btnsLeftWidth, openedLeft: true, openedRight: false });
}
}
,
I add this function to open swipeout manually, it works only when I touched swipeout content at least once. Actually I found solution without trying to touch once, which write the direct width in btnsRightWidth and btnsLeftWidth variable but it's not universal way at all. What do you think about?
This line yields:
2016-01-29 13:38:22.549 [trace][tid:com.facebook.React.JavaScript] onOpen: -1 -1
Hi,
I am experiencing slow performance (lagging) when I run your example code. Both on Xcode simulator and when built on Iphone 6. everything is up-to-date (xcode, ios).
any ideas? thanks.
I followed the wiki on disabling the scrolling on lists when swiping:
https://github.com/dancormier/react-native-swipeout/wiki/Scrolling
Which works, but when you have large lists (~60+ rows), the swipeout is slow to respond because it's setting state on the list constantly.
I managed to modify the suggested code to first check if the scrollEnabled
value has changed and it's a little bit quicker:
allowScroll(scrollEnabled) {
if (this.state.scrollEnabled != scrollEnabled) {
this.setState({ scrollEnabled: scrollEnabled })
}
}
However, after scrolling through the list a few times and then swiping out, it eventually gets clunky. It's more noticeable on an actual device also.
Workarounds? Suggestions?
I did investigation and problem with this style prop
swipeout: {
backgroundColor: '#dbddde',
flex: 1,
-> overflow: 'hidden',
},
Can it be removed or may be another variant ?
Thanks for adding proper Android support! It works quite well, but for one thing: a touch event requires holding the finger very still.
Consider the following components:
<Swipeout right={{component: 'MyButton', onPress: this._onMyButtonPress}} close={true}>
<View>
<TouchableHighlight onPress={this._onRowPress}>
<... />
</TouchableHighlight>
</View>
</Swipeout>
On iOS this works fine, but on Android triggering the TouchableHighlight
is very hard: only a slight movement of the finger during the press triggers the swipeout action, which makes _onRowPress
hard to trigger.
trippcr@ce2b048 on 2.0.9 still works.
Right now this.props.scroll
gets called a lot which means anywhere that calls setState
using this value (ie to disable scrolling in parent) will suffer performance issues.
Running npm start
after installing I get
Error: Naming collision detected: /<path-to-app>/node_modules/react-native/node_modules/fbjs/lib/EventListener.js collides with /<path-to-app>/node_modules/react-native-swipeout/node_modules/react/node_modules/fbjs/lib/EventListener.js
New props: close
, onOpen
, scroll
These changes achieve:
Hi, I'm using react-native-swipeout in a ListView, with the onOpen
prop to show the Swipeout buttons only once, as in the wiki.
However, when the dataSource is updated, the component is rendered again and the swipe gesture is not as fluid as without this trick. Sometimes, it doesn't even open the buttons, making the component unusable.
Do you have also this issue? It cannot be seen on the simulator, just on a real device.
I've just tried this package and it works correctly with that version of RN, would you update the package json to support it and perhaps publish a new release?
I may be approaching this wrong, but once I wrapped the row with Swipeout, the default click state attached to TouchableHIghlight (e.g. this._getTrackedItems( aircraft)
) stopped triggering.
<TouchableHighlight
underlayColor='white'
onPress={() => { this._getTrackedItems( aircraft ) }}>
<View>
<Swipeout
right={swipeoutBtns}
autoClose='true'
backgroundColor= 'transparent'>
<View style={styles.rowContainer}>
<View style={styles.countContainer}>
<Text style={styles.count}>
{aircraft.ti_count}
</Text>
<Text style={styles.countLabel}>
TI's
</Text>
</View>
<View style={styles.aircraftContainer}>
<Text style={styles.aircraft}>
{aircraft.reg_number}
</Text>
<Text style={styles.cacheLabel}>
last updated: July 18, 2015 at 2:35 PM
</Text>
</View>
</View>
</Swipeout>
<Separator />
</View>
</TouchableHighlight>
For my understanding, OnOpen should be triggered when the user clicks on the item itself and not when the user swipes left or right. However, OnOpen is being triggered whenever the user interacts with the component. Can you fix this? (Since TouchableHighlight is no alternative)
There is currently an onOpen callback - it would be handy if there were an onClose callback as the buttons/components I have maintain state that I'd like to reset between open/close cycles.
How difficult would this be to implement?
The dependency on react-tween-state
is causing these to be pulled in which is not desirable:
βββ [email protected]
βββ [email protected] ([email protected], [email protected])
There seems to be an issue with PanResponder and 3D touch on new iPhone devices. A TouchableHighlight inside a Swipeout component does not respond to its onPress handler. This issue has been raised in the react-native project (facebook/react-native#3082) but could also be handled in react-native-swipeout by looking at the position of the child component (see facebook/react-native#3082 (comment)).
Hi, this package looks awesome. I would love to implement something similar on a hover event on a React component for the web. Any tips on the translation? This is not super relevant to the project so feel free to close if you don't have an answer. Thanks!
How do you pass a custom property such as a 'row id' to an onPress function on your swipeoutBtns? Since these actions are meant to act on list items, this seems like an obvious need. However I can't find how you approach this in any of your examples?
eg.
onPress: function(id) { console.log('You clicked the button on row ' + id); }
??
When you set
scrollEnabled={this.state.scrollEnabled}
Looking at the RN docs and code, there doesnt seem to be any hook for a scrollEnabled property on a list view to lock scrolling. Am I missing something? Did you extend the ListView component?
Great plugin, thank you. Just a heads up that it's not compatible with Android.
Attempt to invoke virtual method 'android.view.ViewParent android.view.View.getParent()' on a null object reference
React Native v0.14.2
After installing react-native-swipeout to my functioning app, I get the following error from React-Native:
"TransformError: /app/node_modules/react-native-swipeout/node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationContext.js: This transform does not support getter methods for ES6 classes. (line: 53, col: 2)."
Any idea how I can remedy this? Thanks!
Firstly, this is amazing!! I love it, thank you! (been wanting to say that for a few days).
My question..
I can see that you can add a function inline by:
var Swipeoutbuttuns = [
{
text: "MyButton",
onPress: function(){ alert('button pressed') },
}
]
but what if I have a function already?
e.g.
var rowData = {someData};
myFunction: function(data){
// do something with data and ref "componentRef"
},
render: function(){
var Swipeoutbuttuns = [
{
text: "MyButton",
onPress: function(){ this.myFunction(rowData) },
}
];
return (
<Swipeout right={swipeoutbuttons} ref="componentRef">
// my layout using rowData
</Swipeout>
}
I considered passing in a custom component but figure that I'll have the same issues as I can't passProps to it either?
Hey @dancormier, I'm having some issues getting this to work on the 6s+. It works as expected on every other device I've tested, but a child TouchableHighlight does not respond to being pressed on a 6s+. This may be an issue with react-native itself.
The swipeout action itself works, but the panResponder appears to block the onPress from firing on child elements. I did some research and found https://botbot.me/freenode/reactnative/2015-08-28/?page=8 which refers to a similar issue, though I was wondering whether something in the new "3d touch" that may get in the way of correctly passing the onPress action.
Why is the container red
:
react-native-swipeout/index.js
Line 251 in 1af666e
When swiping left and not keeping it exactly on a line the parent scrollView
will also scroll. That's a bit annoying and not how a native UITableView works.
I've tried applying directionalLockEnabled={true}
to it but I assume that only works for it's own pan handler.
Hello,
I am using this plugin and really this is very good. Really good work. π
I am trying to use this into ListViews. I am facing below issues:
This does not work correctly since the onpress never makes it to the parent.
<Listitem
onPress={() => {....;}}
backgroundColor='#EEE' >
<Swipeout right={swipeoutBtns} style={{backgroundColor: '#EEE'}}>
....
Hell of a bug=)
It started after moving to 0.14.2 from 0.13.1.
If I remove Swipeout the list becomes visible and updated properly after these actions. Also was working with Swipeout and 0.13.1
Hi, Dan!
There is a problem with using a label for swipeout component with a long word, such as "Unsubscribe". The label breaks in two lines. It happens because the the width is limited to 1/5 of Device width.
I've tried to use button component to use a custom View with fixed width, but it didn't fix the issue.
I see two ways to fix this problem:
What do you think about it?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.