How do I detect when a longPress is released (not by dragging away). onPressOut does say when it's released but it also triggers when finger is dragged away from the button.
<TouchableWithoutFeedback
onLongPress={() => this.onLongPress()}
onPressOut={() => this.onCancel()}
onPressIn={() => this.onHover()}
onPress={() => this.onPress()}
>
How about adding a massive (bigger than the screen) pressRetentionOffset? This should prevent the touch from cancelling unless you release.
<TouchableWithoutFeedback
...
pressRetentionOffset={{ top: 1000, left: 1000, bottom: 1000, right: 1000 }}
>
Are you sure you should do that?
Cancel-ability- when making an action, the user should be able to abort it mid-touch by dragging their finger away
from Facebook's Best Practices section:
https://facebook.github.io/react-native/docs/gesture-responder-system.html#best-practices
If you still need to do it, you may need to implement a custom touchable using View.props.onResponderMove and View.props.onResponderRelease
See docs:
https://facebook.github.io/react-native/docs/gesture-responder-system.html#responder-lifecycle
Related
with WooCommerce 4.2, on iOS, FlexSlider (v2.7.2) show a bug with a horizontal slider: when the focus is on the slider as the user swipes left or right, the vertical scroll is still active, there is some level of vertical movement. That makes the slider "rebound".
You can see the bug in this video: https://youtu.be/bM8zcv3ciTo
EDIT: My question is similar to this one, but related to Flexslider.
I have this in functions.php:
/*PRODUCT PAGE FlexSlider Options*/
add_filter( 'woocommerce_single_product_carousel_options', 'filter_single_product_carousel_options' );
function filter_single_product_carousel_options( $options ) {
if ( wp_is_mobile() ) {
$options['controlNav'] = true; // Option 'thumbnails' by default
$options['direction'] = "horizontal";
$options['slideshow'] = false; // Already "false" by default
}
return $options;
}
Any idea how to prevent this vertical scroll while the focus is on the Flexslider?
Anybody also has this bug?
I installed a test site with only Wordpress and WooCommerce, and the bug is here, so it's not plugin-related: http://woo.makemy.biz/produit/produit-de-test/
Edit: Adapting the owl carousel solution would result in code that looks like this:
//You should replace ".myFlexslider" with an appropriate class.
jQuery('.myFlexslider').data('flexslider').vars.before = function(){
jQuery('body').css('overflow', 'hidden');
};
jQuery('.myFlexslider').data('flexslider').vars.after = function(){
jQuery('body').css('overflow', '');
};
which should work. https://codepen.io/Terrafire123/pen/YzWRXOJ
It's not possible to do this via PHP, because PHP doesn't expose the API necessary to do this.
You should know, that preventing vertical scroll when the slider swipes is usually discouraged because this can result in the slider being annoyingly difficult to scroll past.
Original answer: The fact that the issue seems to occur with both Flickity and Flexsider seems to indicate that it isn't a problem with either one, but rather with the user.
A careful review of the Youtube video you have seems to indicate it's working correctly, and there is no real bug. Every time the slider doesn't move in your video, it's because
a. He's sliding vertically, not horizontally, or
b. He's sliding in a direction he can't slide because loop is disabled and he's at the first element.
The rebound effect is normal when you scroll to the top of the page in iOS. If desired, you can disable the bouncing effect with a workaround like this:
html {
position: fixed;
height: 100%;
overflow: hidden;
}
body {
width: 100vw;
height: 100vh;
position:relative;
overflow:auto;
-webkit-overflow-scrolling: touch;
}
I've got an app which leverages a WKWebView for most of the content. In a few screens we have buttons in a div which leverages position: fixed; so that they're always in the same place as a long form scrolls underneath. When the virtual keyboard is shown I add a class to the document body that can be used to adjust other things, for example, tweaking the bottom property on the div containing these buttons so they move above the keyboard.
So far, so good, they're always visible. The problem arises when the form is then scrolled, the buttons visibly move up with the rest of the page (which they shouldn't), but the browser actually acts as if they're still position where they're supposed to be. The screen shot shows where the browser believes the buttons are, and if you touch those areas then the buttons get activated.
I'm happy to chalk this up as a bug with WebKit or specifically WKWebView, but is there a known workaround for this so that they render in the correct place? I read that adding a translation to trigger hardware rendering could help, but it doesn't seem to have done the job here. I also read that changing the position to absolute could solve this issue, but for me it just results in them being rendered off screen somewhere altogether.
You can add fixed position to button wrapper
.btn-bar-fixed {
position: fixed;
bottom: 0px;
right: 0px;
}
In ionic 3 ,Using iPhone when sliding ionic slider the vertical scrolling occur, it causes app ui experience. it’s serious bug I have tried many ideas in googling no one works. please help me any one aware of this issue
We had the same problem with some sliders on our project. The first slide was ok, you could slide left & right without any vertical scroll, however any further slides would scroll the whole page up & down. What fixed it for us was to add the following css:
.swiper-wrapper{
width:auto !important;
}
The .swiper-wrapper was width: 100%, and then being pushed to the left (and off screen) when scrolled. So any further swipes on the slider were outwith the swiper-wrapper thus causing the whole page to move.
i have the solution!
ionSlideDrag Emitted when a slide moves. When the slide moves i call a function which add a class to my content which add
overflow-y: hidden.
ionSlideDidChange Emitted when a slide change ends. it means that when slide change ends i call a function which remove the class and my content is again scrollable.
For add and remove class i have implemented jquery. ( How can I use jQuery with Ionic 2?)
this is an example of my code:
in my view.html
<ion-slides slidesPerView="4" spaceBetween="20" (ionSlideDrag)="dragging()" (ionSlideDidChange)="endDragging()">
<ion-slide *ngFor="let action of actionPages">
<img [src]="url + action.imgSmall">
<h1></h1>
</ion-slide>
</ion-slides>
in my view.ts
dragging(){
$("#contenitore").addClass("no-scroll")
}
endDragging(){
$("#contenitore").removeClass("no-scroll")
}
no-scroll class in app.scss:
.no-scroll {
div.scroll-content {
overflow-y: hidden;
}
}
I am new to React Native. I have an app with a ScrollView component and several custom components inside it. I would like to trigger an onPressOut event from the ScrollView, so that when the user scrolls, and releases, the child components inside the ScrollView update their states. But, the ScrollView documentation does not include any press events: https://facebook.github.io/react-native/docs/scrollview.html
Other things I tried:
I tried wrapping the scrollview inside a TouchableWithoutFeedback component, when I do this, I get an error as soon as I try to scroll:
2015-10-26 11:59:13.849
[error][tid:com.facebook.React.ShadowQueue][RCTModuleMethod.m:60]
Argument 0 (NSNumber) of RCTUIManager.measure must not be null
2015-10-26 11:59:13.850 [error][tid:com.facebook.React.ShadowQueue][RCTModuleMethod.m:60]
Argument 0 () of RCTUIManager.measure could not be processed.
Aborting method call.
No idea what that means...
Any ideas? Thanks!
Here is my code:
<View ref="theWrapperView" style={styles.theWrapperView}>
<ScrollView
onScroll={this.onScroll.bind(this)}
onMomentumScrollEnd={this.onScrollAnimationEnd.bind(this)}
style={styles.scrollView}
contentContainerStyle={styles.scrollViewContentContainer}
showsHorizontalScrollIndicator={true}
scrollEventThrottle={10}
pagingEnabled={true}
horizontal={true}
automaticallyAdjustContentInsets={false}
snapToAlignment={'center'}
snapToInterval={20}
zoomScale={1.5}
centerContent = {true}
>
{cards}
</ScrollView>
</View>
When I change the View element to a TouchableWithoutFeedback element is when I get the error.
I have figured this out after investigating the React Native source code: https://github.com/facebook/react-native/blob/master/Libraries/Components/ScrollResponder.js
As it turns out there are actually a number of other events available via the ScrollResponder mixin, that are not mentioned in the online documentation. It is not necessary to include the mixin to access these events, since they are already part of the ScrollView component. The one that was useful for me was onResponderRelease, which fires when you release the ScrollView, like so:
<View ref="theWrapperView" style={styles.theWrapperView}>
<ScrollView
onScroll={this.onScroll.bind(this)}
onMomentumScrollEnd={this.onScrollAnimationEnd.bind(this)}
onResponderRelease = {this.onResponderReleaseHandler.bind(this)}
>
{cards}
</ScrollView>
</View>
and in the class define a handler:
onResponderRelease(){
//do stuff
}
onTouchEnd will help you to get this
<ScrollView contentContainerStyle={{ paddingHorizontal: 22, top: -16 }}
onTouchEnd={(e) => {
//Here define your ScrollView Press Event
}}
>
{this.props.children}
</ScrollView>
I need to keep the scroll offset of an element in sync with another (the window actually) and I'm having trouble doing so during the inertial "roll off" phase of scrolling on Mobile Safari (iPad).
I have a couple of divs with position:fixed; overflow:hidden and I need to keep their scroll offset in sync with the window's one (meaning the entire body scroll.) Usually I'd code it like this (jQuery):
var $win = $(window),
$div1 = $(...)
$win.scroll(function() {
$div1.scrollTop($win.scrollTop())
})
But testing the interface on an iPad, I noticed that the div was not being updated neither during the touch phase, when you are dragging the virtual page with your finger, nor during the inertial phase, when you let go and the page slows down to a stop.
I solved it for the dragging phase by registering the handler for the touchmove event as well as the scroll one.
But I can't find a way to solve the problem for the inertial phase. The div stays still (and goes slowly out of sync with the rest of the page) until the inertial movement comes to a full stop, when the scroll event is finally fired and it skips into position.
Here's a working demo.
Try to scroll it on an iPad to see the "inertial scolling" problem. Unfortunately I couldn't get it to work on jsFiddle, due to the iPad's weird behaviour with iframe scrolling.
If I could just run a polling during that phase, I could keep a semblance of synchronization between the two elements. I've tried with setTimeout, setInterval, and requestAnimationFrame, but neither of them fires during the inertial scrolling phase. It seems like all Javascript stops during that phase.
Questions:
Is there any touch or scroll event fired during the inertial scrolling phase?
Is there any way to run a Javascript callback during that phase?
Is there a way to sync the scroll offset of two elements (either X or Y, not both) using CSS or some other technology other than JS?
OldDrunkenSailor beat me to suggesting iScroll.
Unfortunately, out of the box iScroll just replicates the same problem as native inertial scrolling -- there's no event handling during the inertial phase.
Here's a version of your demo with a monkey-patched iScroll to add a custom event that fires even during the inertial stage: https://dl.dropbox.com/u/15943645/scrollingdemo.html
Works great on my 2nd gen iPad.
JS:
// Disable touch events
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
// Patch iScroll for position change custom event
iScroll.prototype._oldPos = iScroll.prototype._pos;
iScroll.prototype._pos = function(x, y) {
this._oldPos(x, y);
if (this.options.onPositionChange) this.options.onPositionChange.call(this);
}
$(function() {
var $win = $(window),
$div_cols = $('#cols'),
$div_rows = $('#rows'),
$div_body = $('#body')
// attach scrolling sync handler and execute it once
function sync_scroll(e) {
$div_cols.scrollLeft(0 - $div_body.position().left);
$div_rows.scrollTop(0 - $div_body.position().top);
}
// initialize iScroll on wrapper div, with position change handler
var myScroll = new iScroll('iscroll_wrapper', {
bounce: false,
onPositionChange: sync_scroll
});
})
CSS:
#iscroll_wrapper {
position:absolute;
z-index: 1;
left: 168px;
top:77px;
bottom:0px;
right:0;
overflow:auto;
}
#body {
position:absolute;
z-index: 1;
width: 2046px;
height: 3376px;
}
Note only the body responds to touch events, but you can extend the technique to the rows and cols divs for the reverse relationship.
iOS actually freezes DOM manipulation and Javascript while inertial scrolling is happening. Here is a simple demo that I made to illustrate the difference between scrolling in a normal desktop environment vs the iPad: http://jsfiddle.net/notjoelshapiro/LUcR6/. This code only has this JS in it:
var num = 0;
function updateNum(){
num++;
$('#awesomeDiv').text(num);
}
$(window).scroll(updateNum);
On scroll it increments a number and displays it on the bottom of the page. You'll see that the scroll number at the bottom of the screen is only being incremented when the inertial scroll has stopped. If Javascript was acting in the background it wouldn't refresh until the scroll ended but the number should be incremented higher.
So to answer your questions specifically:
Is there any touch or scroll event fired during the inertial scrolling phase?
Negative, ghostrider.
Is there any way to run a Javascript callback during that phase?
See above.
Is there a way to sync the scroll offset of two elements (either X or Y, not both) using CSS or some other technology other than JS?
Not quite sure what you mean here, JS can do all of the math'ing that you need but it will have to be when inertial scroll has completed. To be honest though, this may be a symptom of tl;dr since I'm at work right now.
Have you looked at the iScroll library? It simulates intertial (or non-inertial) scrolling for touch and non-touch environments and gives you JS callbacks during/after "scroll" and "inertial scroll" and provides a lot of information that you can use to calculate where you are on the page.
Triggers when a scroll begins. Note that iOS devices freeze DOM manipulation during scroll, queuing them to apply when the scroll finishes. We're currently investigating ways to allow DOM manipulations to apply before a scroll starts.
http://jquerymobile.com/demos/1.0rc1/docs/api/events.html#/demos/1.0rc1/docs/api/events.html
Thats what they had to say under scroll start section