Commit Graph

39 Commits

Author SHA1 Message Date
Nick Lockwood 688bb17777 Fixed sticky header touch handling bug
Summary:In order to ensure that the docked sticky header in a ListView receives touches correctly, RCTScrollView has a custom hitTest implementation that checks the sticky headers for touches prior to checking any other views.

There was a bug in this implementation that meant that sticky views would get touch priority even if the touch was outside the bounds of the scrollView. This meant that sticky headers that scrolled off the top of the list would intercept touches intended for views placed above the scrollView.

This diff fixes that bug by checking that the touch is inside the scrollview before checking for sticky header touches. I've also limited the custom hit test logic to just the currently docked header, as the other sticky header views do not require special treatment.

Reviewed By: javache

Differential Revision: D3041236

fb-gh-sync-id: a2a3474dda03d5b51688bd575195a67956184bbe
shipit-source-id: a2a3474dda03d5b51688bd575195a67956184bbe
2016-03-14 04:08:21 -07:00
Kyle Corbitt 299cd4cd01 Fix empty ScrollView warnings
Summary:Currently, an empty `<ScrollView />` on iOS always throws the warning "Sticky header index 0 was outside the range {0, 0}".

This is because the error-reporting code relies on the assumption that `stickyHeaderIndices` exists, and when it doesn't the error check thinks there's an index when there really isn't.

Note that this only changes error reporting and won't affect apps out of debug mode.

**Test plan**
I created a sample app and included an empty `<ScrollView />`. Without this change the "Sticky header..." warning was displayed on every run through. With this change implemented, the warning went away.
Closes https://github.com/facebook/react-native/pull/6417

Differential Revision: D3042178

Pulled By: nicklockwood

fb-gh-sync-id: 7afefd428a5fcb03867bcb69e46c46fe1ae9151e
shipit-source-id: 7afefd428a5fcb03867bcb69e46c46fe1ae9151e
2016-03-11 12:24:22 -08:00
Nick Lockwood 62177dbb3b Removed defaultViews
Summary:When a component prop is set to null/undefined, and doesn't have a default value specified in `getDefaultProps`, the null value is sent over the bridge as a sentinel to reset to the original native value.

On iOS this is handled by creating a default view instance for each view type. The default view is then used to look up the unmodified value for any prop that is reset.

This is rather expensive however, as it means that for complex views (e.g. WebView, MapView), a minimum of two instances will be created even if only one is needed, and the default view will remain even after all actual view instances have been released.

This diff replaces the default view mechanism with a system where the default value of each prop is recorded the first time it is set. This avoids the need to keep an extra copy of the whole view.

The only exception is for props that use the `RCT_CUSTOM_VIEW_PROPERTY` macro, which includes the default view as part of the interface. To avoid a breaking change, a default view will still be created for views that use this macro, but only if they are sent a null value (so very rarely, in practice). In a future update we may deprecate or replace `RCT_CUSTOM_VIEW_PROPERTY` if there are significant benefits to doing so.

Reviewed By: javache

Differential Revision: D3012115

fb-gh-sync-id: 259348e54aa8342f444ad182b6f883d2dd684973
shipit-source-id: 259348e54aa8342f444ad182b6f883d2dd684973
2016-03-09 08:56:46 -08:00
Janic Duplessis 102a31c13e Fix RefreshControl layout on screen rotation and consecutive pull to refresh not working properly
Summary:Fixes the RefreshControl layout after a screen rotation. See #6311 for a more detailed explanation. I fixed it by adjusting the frame of the RefreshControl in `layoutSubviews` of the parent ScrollView.

While working on fixing this I noticed that when doing a 'pull to refresh' and then not scrolling and wait for it to end the next one will not behave like the first one (it will require pulling further down for the spinner to start spinning). I fixed that too by scrolling the scrollview back to 0 manually before calling `UIRefreshControl.endRefreshing`.

**Test plan (required)**
Tested using the UIExplorer RefreshControl example.

When doing a pull to refresh and then rotating the screen the RefreshControl must stay positioned properly.
Doing multiple consecutive pull to refresh without scrolling after should all behave the same.

Fixes #6311
Closes https://github.com/facebook/react-native/pull/6359

Differential Revision: D3023727

fb-gh-sync-id: f50ae52ea769c2b3e5025c362544a8809a71aa00
shipit-source-id: f50ae52ea769c2b3e5025c362544a8809a71aa00
2016-03-08 04:00:34 -08:00
Janic Duplessis 671b975d92 Fix a bug with ListView with sticky headers + RefreshControl
Summary:The bug is caused by a weird race condition. What happens is that when calling `UIRefreshControl#endRefreshing` the `UIScrollView` delegate `scrollViewDidScroll` function is called synchronously and then `dockClosestSectionHeader` crashes because the sticky header indexes are updated but not the contentView children.

I fixed it by adding an updating property on `RCTRefreshControl` and setting it before calling `endRefreshing` so we can know not to call `dockClosestSectionHeader` at that moment.

Tested with both `RefreshControl` and `onRefreshStart` prop.

I reproduced the bug by replacing ListViewExample.js in UIExplorer with https://gist.github.com/janicduplessis/05fc58e852f3e80e51b9

Fixes #5440

cc nicklockwood
Closes https://github.com/facebook/react-native/pull/5445

Differential Revision: D2953984

Pulled By: nicklockwood

fb-gh-sync-id: c17a6a75ab31ef54d478706ed17a8115a11d734e
shipit-source-id: c17a6a75ab31ef54d478706ed17a8115a11d734e
2016-02-19 05:55:36 -08:00
Nick Lockwood 194273f5f5 Fixed hitTest crash due to sticky header out-of-range
Reviewed By: javache

Differential Revision: D2932227

fb-gh-sync-id: 05d69ec391685dd7e72d3d5f7d56b189a6eab413
shipit-source-id: 05d69ec391685dd7e72d3d5f7d56b189a6eab413
2016-02-12 09:28:21 -08:00
Janic Duplessis 34389c529d Fix sticky headers position when scrolling while RefreshControl is refreshing
Summary:
When scrolling while RefreshControl is refreshing the sticky headers are offset by the height of the UIRefreshControl. This simply removes the height of the UIRefreshControl while it is refreshing and fixes the problem.

You can repro the bug using this example in UIExplorer by doing a pull to refresh and scrolling the ListView immediately after.
https://gist.github.com/janicduplessis/26b4f2758e90b2aa1620

Fixes #5405
Closes https://github.com/facebook/react-native/pull/5517

Reviewed By: svcscm

Differential Revision: D2895623

Pulled By: nicklockwood

fb-gh-sync-id: 81df36cccfc3e7b973c2be78565f8b8408c9fc12
2016-02-03 08:00:42 -08:00
Martin Kralik 7f2b72528e RCTEvent protocol changes (3/7)
Summary:
I want to use the `RCTEvent` protocol for touch events as well. That's why I'm removing not very well defined `body` property and replacing it with `arguments` method, which will return an array that will be passed directly to the js call.
I think this makes sense because there is no unified arguments format for all events and and the called  js method (`moduleDotMethod`) is already event specific.
This way touch events and scroll events can result in calling a completely different js function with a completely different arguments (what they indeed currently do).

public
___
//This diff is part of a larger stack. For high level overview what's going on jump to D2884593.//

Reviewed By: nicklockwood

Differential Revision: D2884590

fb-gh-sync-id: 2c1885c3414e255d8572c0fbbbfe62a23d94dd06
2016-02-03 05:23:50 -08:00
Martin Kralik 3e89c3ea3b removed `coalescingKey` from events (2/7)
Summary:
This property was never used, so I'm removing it.

public
___
//This diff is part of a larger stack. For high level overview what's going on jump to D2884593.//

Reviewed By: javache

Differential Revision: D2884587

fb-gh-sync-id: acd5e576cd13a02e77225f3b308232f8331d3b61
2016-02-03 05:23:43 -08:00
Jean Regisser b84f5fb6c9 Added iOS indicatorStyle prop to ScrollView
Summary:
Hi,

The doc wording was adapted from https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIScrollView_Class/#//apple_ref/doc/c_ref/UIScrollViewIndicatorStyle

Note that the iOS doc is misleading, and `UIScrollViewIndicatorStyleDefault` is the same as `UIScrollViewIndicatorStyleBlack` (since iOS 7 I think).

Let me know what you think.
Closes https://github.com/facebook/react-native/pull/5583

Reviewed By: svcscm

Differential Revision: D2870011

Pulled By: nicklockwood

fb-gh-sync-id: d28a96e1a2d4610cbeaee0ae70108ab9d9f05fdb
2016-01-27 10:16:33 -08:00
Janic Duplessis 44f7a00e95 Cross platform PullToRefreshView component
Summary:
Both iOS and Android currently support some sort of native pull to refresh control but the API was very different. I tried implementing a component based on PullToRefreshViewAndroid but that works on both platforms.

I liked the idea of wrapping the ListView or ScrollView with the PullToRefreshView component and allow styling the refresh view with platform specific props if needed. I also like the fact that 'refreshing' is a controlled prop so there is no need to keep a ref to the component or to the stopRefreshing function.

It is a pretty rough start so I'm looking for feedback and ideas to improve on the API before cleaning up everything.

On iOS we could probably deprecate the onRefreshStart property of the ScrollView and implement the native stuff in a PullToRefreshViewManager. We could then add props to customize the look of the UIRefreshControl (tintColor). We could also deprecate the Android only component and remove it later.
Closes https://github.com/facebook/react-native/pull/4915

Reviewed By: svcscm

Differential Revision: D2799246

Pulled By: nicklockwood

fb-gh-sync-id: 75872c12143ddbc05cc91900ab4612e477ca5765
2016-01-04 08:00:29 -08:00
Pieter De Baets 67bf0f1a70 Avoid interrupting scrolling in nested scrollviews
Summary:
When we nest scrollviews, the hack in handleCustomPan: will cause the scroll to stall and break.

There's still some weird behaviour inside ScrollResponder.js but this does not seem the affect the scrollview's scrolling.

public

Reviewed By: fionaf, jingc, majak

Differential Revision: D2713639

fb-gh-sync-id: ad898ead62415bc14c91bc84fdfdb8c0fbb32b06
2015-12-03 06:19:30 -08:00
Pieter De Baets 38db6fa465 Remove scrollview support from UIManager, remove mainScrollView(delegate)
Reviewed By: nicklockwood

Differential Revision: D2692749

fb-gh-sync-id: 48975d2f09f3b2902dfa2e56ff9d34257b2395bc
2015-11-25 04:12:34 -08:00
EwanThomas 2faf8632d3 UIRefreshControl added to scroll view
Summary: **What:**

adds `onRefreshStart` property to `ScrollView.js` for displaying and activating pull to refresh.

**Why:**

Javascript implementations seemed a little flakey and inconsistent.  As you can see in the issues below:

https://github.com/facebook/react-native/issues/2356
https://github.com/facebook/react-native/issues/745

So this is an attempt a completely native implementation.

What do you think?

![Image of dog](http://i.imgur.com/HcTQnzJ.gif)
Closes https://github.com/facebook/react-native/pull/4205

Reviewed By: svcscm

Differential Revision: D2674945

Pulled By: nicklockwood

fb-gh-sync-id: 65113a5db9785df5a95c68323c2cdf19f3b217b1
2015-11-19 11:15:48 -08:00
Nick Lockwood fa0b45c58b Replaced RCTSparseArray with NSDictionary
Reviewed By: jspahrsummers

Differential Revision: D2651920

fb-gh-sync-id: 953e2ea33abfc7a3a553da95b13e9ab2bccc5a1c
2015-11-14 10:28:28 -08:00
Nick Lockwood c5b990f65f Added lightweight generic annotations
Summary: public

Added lightweight genarics annotations to make the code more readable and help the compiler catch bugs.

Fixed some type bugs and improved bridge validation in a few places.

Reviewed By: javache

Differential Revision: D2600189

fb-gh-sync-id: f81e22f2cdc107bf8d0b15deec6d5b83aacc5b56
2015-11-03 14:49:30 -08:00
Mike Armstrong 23564fe65a reduce leeway to 1, child clipping updated every scroll movement. This fixes scroll view behaviour
Reviewed By: @jspahrsummers

Differential Revision: D2479961
2015-09-25 10:24:02 -07:00
rxb dcf245a9a2 Definable distance pagination for ScrollView
Summary: This is an enhancement for ScrollView that adds the ability to paginate based on a width other than the width of the ScrollView itself. This is a fairly common pattern used on apps like Facebook, App Store, and Twitter to scroll through a horizontal set of cards or icons:

![img_8726 2](https://cloud.githubusercontent.com/assets/451050/8017899/39f9f47c-0bd2-11e5-9c1d-889452f20cf7.PNG) ![img_8727 2](https://cloud.githubusercontent.com/assets/451050/8017898/39f962dc-0bd2-11e5-98b4-461ac0f7f21b.PNG)  ![img_8728 2](https://cloud.githubusercontent.com/assets/451050/8017900/39fd91a4-0bd2-11e5-8786-4cf0316295a0.PNG)

After trying to accomplish this only with JS, it appears that attempting to take over an in-progress native scroll animation with JS is always going to result in some amount of jankiness and jumping.

This pull request uses `scrollViewWillEndDragging` in RCTScrollView.m to adjust `targetContentOffset` based on two new optional props added to ScrollView. `snapToInterval` sets the multiple that the
Closes https://github.com/facebook/react-native/pull/1532

Reviewed By: @​svcscm, @​trunkagent

Differential Revision: D2443701

Pulled By: @vjeux
2015-09-23 11:47:25 -07:00
Alexey Lang bbeaac5d3b Automatically adjust content inset after view controller did layout subviews 2015-09-04 07:00:21 -08:00
Nick Lockwood 88e0bbc469 Ran Convert > To Modern Objective C Syntax 2015-08-25 01:08:49 -08:00
Nick Lockwood 8d1e02b8bd Convert alloc/init to new to please linter 2015-08-17 08:46:00 -07:00
Alex Akers 672b77f355 Perform clip update on RCTScrollView in increments of 50 pt
Summary:
This diff removes calls to `-updateClippedSubviews` by only re-clipping when the scroll view moves by a certain number of pixels.

leeway = 50pt => 46.9% of calls removed
leeway = 10pt => 13.2% " " "
2015-08-13 07:56:41 -08:00
Nick Lockwood 48af214216 Simplified event registration
Summary:
Our events all follow a common pattern, so there's no good reason why the configuration should be so verbose. This diff eliminates that redundancy, and gives us the freedom to simplify the underlying mechanism in future without further churning the call sites.
2015-08-11 06:41:04 -08:00
Tj d8f43105ed [ListView] Fix RCTScrollView stickyHeader touch passing.
Summary:
Point must be converted to the stickyHeader's coordinate space and then passed to the stickyHeaders hitTest:withEvent: method in order to be correctly routed to any subviews of the stickyHeader.

This resolves this [issue](https://github.com/facebook/react-native/issues/2075).
Closes https://github.com/facebook/react-native/pull/2224
Github Author: Tj <tfallon@Tjs-MBP.local>
2015-08-04 17:10:19 -08:00
Zack Gomez 60c8abcc70 Revert "[ReactNative] revert "prevent ScrollView content offset from changing during layout"" 2015-07-29 17:23:18 -08:00
Kevin Gozali 87ce2d635b [ReactNative] revert "prevent ScrollView content offset from changing during layout" 2015-07-28 19:39:56 -08:00
Zack Gomez 068f396c9b [ReactNative] prevent ScrollView content offset from changing during layout
Summary:
-[UIScrollView setFrame:] changes the content offset, which we want to do manually.  Preserve the old offset during layout.
2015-07-28 14:36:27 -08:00
Martín Bigio 66d3f3c616 [rn] Keep native ListView child frames in sync on JS wrapper
Summary: At the moment the `ListView.js` `_childFrames` variable is only updated on scroll. As a consequence, `onChangeVisibleRows` won't get triggered for the initial render, nor any future render not trigered by scroll events. To fix this we need to make sure native and JS have the child frames in sync.
2015-07-07 07:40:56 -08:00
Param Aggarwal 0f2d8e662e [ScrollView] Pick data from older event on coalescing.
Summary:
The `ScrollView` sends important `updatedChildFrames` data to the `ListView` to be able to implement `onChangeVisibleRows` method. Coalescing operates very strongly on older devices like the iPhone 4s where this data is then lost.

Fixes #1782.

`ListView` has a method called `onChangeVisibleRows` that is called whenever the rows visible on screen change. This method is critical to be able to implement deletion/creation of views and hence be conservative in memory usage. I have an infinite scrolling view which uses this method to only render the full rows for what is visible on screen and put placeholders for everything else.

In the `RCTEventDispatcher`, we [coalesce events](522fd33d6f/React/Base/RCTEventDispatcher.m (L135-L152)) that are meant to be sent across the bridge. They are [dequeued](522fd33d6f/React/Base/RCTEventDispatcher.m (L180-L188)) on each
Closes https://github.com/facebook/react-native/pull/1783
Github Author: Param Aggarwal <paramaggarwal@gmail.com>
2015-07-06 17:27:40 -08:00
=?UTF-8?q?=E6=AD=A3=E9=9C=96?= 3940b024a0 Add velocity and targetContentOffset for scrollEndDrag event in RCTScrollView
Summary:
In some case, it is very useful to have `velocity` and `targetContentOffset` parameters for `ScrollEndDrag` event. I just added them.
Closes https://github.com/facebook/react-native/pull/1500
Github Author: =?UTF-8?q?=E6=AD=A3=E9=9C=96?= <zhenglin.lzl@alibaba-inc.com>

Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-06-15 12:14:12 -08:00
Nick Lockwood 650fc9de4c Increased warning levels to -Wall -Wextra, and fixed Xcode 7 beta issues
Summary:
@public

I've increased the warning levels in the OSS frameworks, which caught a bunch of minor issues. I also fixed some new errors in Xcode 7 relating to designated initializers and TLS security.

Test Plan:
* Test the sample apps and make sure they still work.
* Run tests.
2015-06-15 07:52:50 -08:00
Tadeu Zagallo 4fc15dbf17 [ReactNative] Implement proper event coalescing 2015-05-27 20:41:20 -08:00
Brent Vatne 95517fca41 [RCTScrollView] Make ScrollView detect taps on sticky headers
Summary:
As per discussion with @nicklockwood in #875, make `RCTScrollView` check its sticky headers for hitTests first.

Closes https://github.com/facebook/react-native/pull/1415
Github Author: Brent Vatne <brent.vatne@madriska.com>

Test Plan:
 Have a sticky header in a ScrollView with a Touchable onPress action, scroll a bit after it docks and try tapping, should respond to tap.
2015-05-26 18:30:22 -08:00
Spencer Ahrens 1497e42fc5 [ReactNative] Properly support overflow: 'visible' on ScrollView
Summary:
We need to unset `clipsToBounds` on both the wrapper and the inner custom
scroll view

@public

Test Plan:
`overflow: 'visible'` actually shows content outside the `ScrollView`
(e.g. for full-bleed horizontal scrollers/carousels).  It doesn't pick up
touches though, which is a wider issue.
2015-05-13 13:24:37 -07:00
Tadeu Zagallo 736d860571 [ReactNative] Fix RCTScrollView setContentInset 2015-05-07 16:56:02 -08:00
Nick Lockwood 790cee6e26 Fixed broken listview header alignment 2015-05-06 10:48:24 -08:00
Marek Cirkos 88b6df9900 Fixed way that ScrollView handles removeClippedSubviews flag 2015-04-20 05:14:56 -08:00
Nick Lockwood 961f301d65 Renamed throttleScrollCallbackMS to scrollEventThrottle 2015-03-30 04:56:59 -08:00
Tadeu Zagallo 20291a02df [ReactNative] s/ReactKit/React/g 2015-03-26 02:42:24 -08:00