Remove scrollview support from UIManager, remove mainScrollView(delegate)

Reviewed By: nicklockwood

Differential Revision: D2692749

fb-gh-sync-id: 48975d2f09f3b2902dfa2e56ff9d34257b2395bc
This commit is contained in:
Pieter De Baets 2015-11-25 03:07:06 -08:00 committed by facebook-github-bot-5
parent fc5a8678d3
commit 38db6fa465
9 changed files with 62 additions and 115 deletions

View File

@ -12,18 +12,19 @@
'use strict'; 'use strict';
var Dimensions = require('Dimensions'); var Dimensions = require('Dimensions');
var NativeModules = require('NativeModules');
var Platform = require('Platform'); var Platform = require('Platform');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var React = require('React'); var React = require('React');
var Subscribable = require('Subscribable'); var Subscribable = require('Subscribable');
var TextInputState = require('TextInputState'); var TextInputState = require('TextInputState');
var RCTUIManager = NativeModules.UIManager; var { UIManager, ScrollViewManager } = require('NativeModules');
var RCTScrollViewConsts = RCTUIManager.RCTScrollView.Constants;
var invariant = require('invariant');
var warning = require('warning'); var warning = require('warning');
import type ReactComponent from 'ReactComponent';
/** /**
* Mixin that can be integrated in order to handle scrolling that plays well * Mixin that can be integrated in order to handle scrolling that plays well
* with `ResponderEventPlugin`. Integrate with your platform specific scroll * with `ResponderEventPlugin`. Integrate with your platform specific scroll
@ -115,7 +116,6 @@ type Event = Object;
var ScrollResponderMixin = { var ScrollResponderMixin = {
mixins: [Subscribable.Mixin], mixins: [Subscribable.Mixin],
statics: RCTScrollViewConsts,
scrollResponderMixinGetInitialState: function(): State { scrollResponderMixinGetInitialState: function(): State {
return { return {
isTouching: false, isTouching: false,
@ -353,16 +353,15 @@ var ScrollResponderMixin = {
*/ */
scrollResponderScrollTo: function(offsetX: number, offsetY: number) { scrollResponderScrollTo: function(offsetX: number, offsetY: number) {
if (Platform.OS === 'android') { if (Platform.OS === 'android') {
RCTUIManager.dispatchViewManagerCommand( UIManager.dispatchViewManagerCommand(
React.findNodeHandle(this), React.findNodeHandle(this),
RCTUIManager.RCTScrollView.Commands.scrollTo, UIManager.RCTScrollView.Commands.scrollTo,
[Math.round(offsetX), Math.round(offsetY)], [Math.round(offsetX), Math.round(offsetY)],
); );
} else { } else {
RCTUIManager.scrollTo( ScrollViewManager.scrollTo(
React.findNodeHandle(this), React.findNodeHandle(this),
offsetX, { x: offsetX, y: offsetY }
offsetY,
); );
} }
}, },
@ -373,16 +372,15 @@ var ScrollResponderMixin = {
*/ */
scrollResponderScrollWithouthAnimationTo: function(offsetX: number, offsetY: number) { scrollResponderScrollWithouthAnimationTo: function(offsetX: number, offsetY: number) {
if (Platform.OS === 'android') { if (Platform.OS === 'android') {
RCTUIManager.dispatchViewManagerCommand( UIManager.dispatchViewManagerCommand(
React.findNodeHandle(this), React.findNodeHandle(this),
RCTUIManager.RCTScrollView.Commands.scrollWithoutAnimationTo, UIManager.RCTScrollView.Commands.scrollWithoutAnimationTo,
[offsetX, offsetY], [offsetX, offsetY],
); );
} else { } else {
RCTUIManager.scrollWithoutAnimationTo( ScrollViewManager.scrollWithoutAnimationTo(
React.findNodeHandle(this), React.findNodeHandle(this),
offsetX, { x: offsetX, y: offsetY }
offsetY
); );
} }
}, },
@ -392,7 +390,11 @@ var ScrollResponderMixin = {
* @param {object} rect Should have shape {x, y, width, height} * @param {object} rect Should have shape {x, y, width, height}
*/ */
scrollResponderZoomTo: function(rect: { x: number; y: number; width: number; height: number; }) { scrollResponderZoomTo: function(rect: { x: number; y: number; width: number; height: number; }) {
RCTUIManager.zoomToRect(React.findNodeHandle(this), rect); if (Platform.OS === 'android') {
invariant('zoomToRect is not implemented');
} else {
ScrollViewManager.zoomToRect(React.findNodeHandle(this), rect);
}
}, },
/** /**
@ -408,7 +410,7 @@ var ScrollResponderMixin = {
scrollResponderScrollNativeHandleToKeyboard: function(nodeHandle: any, additionalOffset?: number, preventNegativeScrollOffset?: bool) { scrollResponderScrollNativeHandleToKeyboard: function(nodeHandle: any, additionalOffset?: number, preventNegativeScrollOffset?: bool) {
this.additionalScrollOffset = additionalOffset || 0; this.additionalScrollOffset = additionalOffset || 0;
this.preventNegativeScrollOffset = !!preventNegativeScrollOffset; this.preventNegativeScrollOffset = !!preventNegativeScrollOffset;
RCTUIManager.measureLayout( UIManager.measureLayout(
nodeHandle, nodeHandle,
React.findNodeHandle(this.getInnerViewNode()), React.findNodeHandle(this.getInnerViewNode()),
this.scrollResponderTextInputFocusError, this.scrollResponderTextInputFocusError,

View File

@ -18,7 +18,6 @@ var RCTScrollView = require('NativeModules').UIManager.RCTScrollView;
var RCTScrollViewManager = require('NativeModules').ScrollViewManager; var RCTScrollViewManager = require('NativeModules').ScrollViewManager;
var React = require('React'); var React = require('React');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var RCTUIManager = require('NativeModules').UIManager;
var ScrollResponder = require('ScrollResponder'); var ScrollResponder = require('ScrollResponder');
var StyleSheet = require('StyleSheet'); var StyleSheet = require('StyleSheet');
var StyleSheetPropType = require('StyleSheetPropType'); var StyleSheetPropType = require('StyleSheetPropType');

View File

@ -44,19 +44,6 @@ RCT_EXTERN NSString *const RCTUIManagerRootViewKey;
*/ */
@interface RCTUIManager : NSObject <RCTBridgeModule, RCTInvalidating> @interface RCTUIManager : NSObject <RCTBridgeModule, RCTInvalidating>
/**
* The UIIManager has the concept of a designated "main scroll view", which is
* useful for apps built around a central scrolling content area (e.g. a
* timeline).
*/
@property (nonatomic, weak) id<RCTScrollableProtocol> mainScrollView;
/**
* Allows native environment code to respond to "the main scroll view" events.
* see `RCTUIManager`'s `setMainScrollViewTag`.
*/
@property (nonatomic, readwrite, weak) id<UIScrollViewDelegate> nativeMainScrollDelegate;
/** /**
* Register a root view with the RCTUIManager. * Register a root view with the RCTUIManager.
*/ */

View File

@ -1095,73 +1095,6 @@ RCT_EXPORT_METHOD(measureViewsInRect:(CGRect)rect
callback(@[results]); callback(@[results]);
} }
RCT_EXPORT_METHOD(setMainScrollViewTag:(nonnull NSNumber *)reactTag)
{
[self addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
// - There should be at most one designated "main scroll view"
// - There should be at most one designated "`nativeMainScrollDelegate`"
// - The one designated main scroll view should have the one designated
// `nativeMainScrollDelegate` set as its `nativeMainScrollDelegate`.
if (uiManager.mainScrollView) {
uiManager.mainScrollView.nativeMainScrollDelegate = nil;
}
id view = viewRegistry[reactTag];
if (view) {
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
uiManager.mainScrollView = (id<RCTScrollableProtocol>)view;
uiManager.mainScrollView.nativeMainScrollDelegate = uiManager.nativeMainScrollDelegate;
} else {
RCTLogError(@"Tag #%@ does not conform to RCTScrollableProtocol", reactTag);
}
} else {
uiManager.mainScrollView = nil;
}
}];
}
// TODO: we could just pass point property
RCT_EXPORT_METHOD(scrollTo:(nonnull NSNumber *)reactTag
withOffsetX:(CGFloat)offsetX
offsetY:(CGFloat)offsetY)
{
[self addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){
UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
[(id<RCTScrollableProtocol>)view scrollToOffset:(CGPoint){offsetX, offsetY} animated:YES];
} else {
RCTLogError(@"tried to scrollToOffset: on non-RCTScrollableProtocol view %@ with tag #%@", view, reactTag);
}
}];
}
// TODO: we could just pass point property
RCT_EXPORT_METHOD(scrollWithoutAnimationTo:(nonnull NSNumber *)reactTag
offsetX:(CGFloat)offsetX
offsetY:(CGFloat)offsetY)
{
[self addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){
UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
[(id<RCTScrollableProtocol>)view scrollToOffset:(CGPoint){offsetX, offsetY} animated:NO];
} else {
RCTLogError(@"tried to scrollToOffset: on non-RCTScrollableProtocol view %@ with tag #%@", view, reactTag);
}
}];
}
RCT_EXPORT_METHOD(zoomToRect:(nonnull NSNumber *)reactTag
withRect:(CGRect)rect)
{
[self addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){
UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
[(id<RCTScrollableProtocol>)view zoomToRect:rect animated:YES];
} else {
RCTLogError(@"tried to zoomToRect: on non-RCTScrollableProtocol view %@ with tag #%@", view, reactTag);
}
}];
}
/** /**
* JS sets what *it* considers to be the responder. Later, scroll views can use * JS sets what *it* considers to be the responder. Later, scroll views can use
* this in order to determine if scrolling is appropriate. * this in order to determine if scrolling is appropriate.

View File

@ -375,7 +375,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
CGRect _lastClippedToRect; CGRect _lastClippedToRect;
} }
@synthesize nativeMainScrollDelegate = _nativeMainScrollDelegate; @synthesize nativeScrollDelegate = _nativeScrollDelegate;
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{ {
@ -542,14 +542,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
- (void)delegateMethod:(UIScrollView *)scrollView \ - (void)delegateMethod:(UIScrollView *)scrollView \
{ \ { \
[_eventDispatcher sendScrollEventWithType:eventName reactTag:self.reactTag scrollView:scrollView userData:nil]; \ [_eventDispatcher sendScrollEventWithType:eventName reactTag:self.reactTag scrollView:scrollView userData:nil]; \
if ([_nativeMainScrollDelegate respondsToSelector:_cmd]) { \ if ([_nativeScrollDelegate respondsToSelector:_cmd]) { \
[_nativeMainScrollDelegate delegateMethod:scrollView]; \ [_nativeScrollDelegate delegateMethod:scrollView]; \
} \ } \
} }
#define RCT_FORWARD_SCROLL_EVENT(call) \ #define RCT_FORWARD_SCROLL_EVENT(call) \
if ([_nativeMainScrollDelegate respondsToSelector:_cmd]) { \ if ([_nativeScrollDelegate respondsToSelector:_cmd]) { \
[_nativeMainScrollDelegate call]; \ [_nativeScrollDelegate call]; \
} }
RCT_SCROLL_EVENT_HANDLER(scrollViewDidEndScrollingAnimation, RCTScrollEventTypeEndDeceleration) RCT_SCROLL_EVENT_HANDLER(scrollViewDidEndScrollingAnimation, RCTScrollEventTypeEndDeceleration)
@ -706,8 +706,8 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, RCTScrollEventTypeMove)
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
{ {
if ([_nativeMainScrollDelegate respondsToSelector:_cmd]) { if ([_nativeScrollDelegate respondsToSelector:_cmd]) {
return [_nativeMainScrollDelegate scrollViewShouldScrollToTop:scrollView]; return [_nativeScrollDelegate scrollViewShouldScrollToTop:scrollView];
} }
return YES; return YES;
} }

View File

@ -19,4 +19,3 @@
@interface RCTScrollViewManager : RCTViewManager @interface RCTScrollViewManager : RCTViewManager
@end @end

View File

@ -70,7 +70,6 @@ RCT_EXPORT_VIEW_PROPERTY(onRefreshStart, RCTDirectEventBlock)
- (NSDictionary<NSString *, id> *)constantsToExport - (NSDictionary<NSString *, id> *)constantsToExport
{ {
return @{ return @{
// TODO: unused - remove these?
@"DecelerationRate": @{ @"DecelerationRate": @{
@"normal": @(UIScrollViewDecelerationRateNormal), @"normal": @(UIScrollViewDecelerationRateNormal),
@"fast": @(UIScrollViewDecelerationRateFast), @"fast": @(UIScrollViewDecelerationRateFast),
@ -118,7 +117,7 @@ RCT_EXPORT_METHOD(calculateChildFrames:(nonnull NSNumber *)reactTag
RCT_EXPORT_METHOD(endRefreshing:(nonnull NSNumber *)reactTag) RCT_EXPORT_METHOD(endRefreshing:(nonnull NSNumber *)reactTag)
{ {
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RCTScrollView *> *viewRegistry) { [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RCTScrollView *> *viewRegistry) {
RCTScrollView *view = viewRegistry[reactTag]; RCTScrollView *view = viewRegistry[reactTag];
if (!view || ![view isKindOfClass:[RCTScrollView class]]) { if (!view || ![view isKindOfClass:[RCTScrollView class]]) {
RCTLogError(@"Cannot find RCTScrollView with tag #%@", reactTag); RCTLogError(@"Cannot find RCTScrollView with tag #%@", reactTag);
@ -126,10 +125,44 @@ RCT_EXPORT_METHOD(endRefreshing:(nonnull NSNumber *)reactTag)
} }
[view endRefreshing]; [view endRefreshing];
}]; }];
} }
RCT_EXPORT_METHOD(scrollTo:(nonnull NSNumber *)reactTag withOffset:(CGPoint)offset)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){
UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
[(id<RCTScrollableProtocol>)view scrollToOffset:offset animated:YES];
} else {
RCTLogError(@"tried to scrollToOffset: on non-RCTScrollableProtocol view %@ with tag #%@", view, reactTag);
}
}];
}
RCT_EXPORT_METHOD(scrollWithoutAnimationTo:(nonnull NSNumber *)reactTag withOffset:(CGPoint)offset)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){
UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
[(id<RCTScrollableProtocol>)view scrollToOffset:offset animated:NO];
} else {
RCTLogError(@"tried to scrollToOffset: on non-RCTScrollableProtocol view %@ with tag #%@", view, reactTag);
}
}];
}
RCT_EXPORT_METHOD(zoomToRect:(nonnull NSNumber *)reactTag withRect:(CGRect)rect)
{
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){
UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
[(id<RCTScrollableProtocol>)view zoomToRect:rect animated:YES];
} else {
RCTLogError(@"tried to zoomToRect: on non-RCTScrollableProtocol view %@ with tag #%@", view, reactTag);
}
}];
}
- (NSArray<NSString *> *)customDirectEventTypes - (NSArray<NSString *> *)customDirectEventTypes
{ {
@ -144,4 +177,3 @@ RCT_EXPORT_METHOD(endRefreshing:(nonnull NSNumber *)reactTag)
} }
@end @end

View File

@ -15,7 +15,7 @@
*/ */
@protocol RCTScrollableProtocol @protocol RCTScrollableProtocol
@property (nonatomic, weak) NSObject<UIScrollViewDelegate> *nativeMainScrollDelegate; @property (nonatomic, weak) NSObject<UIScrollViewDelegate> *nativeScrollDelegate;
@property (nonatomic, readonly) CGSize contentSize; @property (nonatomic, readonly) CGSize contentSize;
- (void)scrollToOffset:(CGPoint)offset; - (void)scrollToOffset:(CGPoint)offset;

View File

@ -719,11 +719,6 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
mOperationsQueue.enqueueShowPopupMenu(reactTag, items, error, success); mOperationsQueue.enqueueShowPopupMenu(reactTag, items, error, success);
} }
@ReactMethod
public void setMainScrollViewTag(int reactTag) {
// TODO(6588266): Implement if required
}
@ReactMethod @ReactMethod
public void configureNextLayoutAnimation( public void configureNextLayoutAnimation(
ReadableMap config, ReadableMap config,