Permalink
Browse files

iOS: Add onScroll event to TextInput

Summary:
Corresponding Android PR: #11001

This adds an onScroll event to TextInput which is useful when a multiline TextInput has so much content that it is scrollable.

**Test plan (required)**

Verified the event works properly in a test app. Also, my team uses this event in our app.

Adam Comella
Microsoft Corp.
Closes #11002

Differential Revision: D4203565

Pulled By: ericvicenti

fbshipit-source-id: 7cb5e10325c3b03c6b395cce0f1bacb0528db40a
  • Loading branch information...
rigdern authored and Facebook Github Bot committed Nov 22, 2016
1 parent 145692a commit c609aee733a7222eadfd98fa4a0d452600b19052
@@ -364,6 +364,12 @@ const TextInput = React.createClass({
* Invoked on mount and layout changes with `{x, y, width, height}`.
*/
onLayout: PropTypes.func,
/**
* Invoked on content scroll with `{ nativeEvent: { contentOffset: { x, y } } }`.
* May also contain other properties from ScrollEvent but on Android contentSize
* is not provided for performance reasons.
*/
onScroll: PropTypes.func,
/**
* The string that will be rendered before text input has been entered.
*/
@@ -652,6 +658,7 @@ const TextInput = React.createClass({
onSelectionChangeShouldSetResponder={emptyFunction.thatReturnsTrue}
text={this._getText()}
dataDetectorTypes={this.props.dataDetectorTypes}
onScroll={this._onScroll}
/>;
}

@@ -811,6 +818,10 @@ const TextInput = React.createClass({
_onTextInput: function(event: Event) {
this.props.onTextInput && this.props.onTextInput(event);
},

_onScroll: function(event: Event) {
this.props.onScroll && this.props.onScroll(event);
},
});

var styles = StyleSheet.create({
@@ -32,6 +32,7 @@
@property (nonatomic, copy) RCTDirectEventBlock onContentSizeChange;
@property (nonatomic, copy) RCTDirectEventBlock onSelectionChange;
@property (nonatomic, copy) RCTDirectEventBlock onTextInput;
@property (nonatomic, copy) RCTDirectEventBlock onScroll;

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;

@@ -106,6 +106,7 @@ - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
#if !TARGET_OS_TV
_scrollView.scrollsToTop = NO;
#endif
_scrollView.delegate = self;
[_scrollView addSubview:_textView];

[self addSubview:_scrollView];
@@ -141,6 +142,11 @@ - (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)index
}
}

- (void)dealloc
{
_scrollView.delegate = nil;
}

- (void)removeReactSubview:(UIView *)subview
{
[super removeReactSubview:subview];
@@ -694,4 +700,31 @@ - (UIColor *)defaultPlaceholderTextColor
return [UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.098/255.0 alpha:0.22];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (_onScroll) {
_onScroll(@{
@"contentOffset": @{
@"x": @(scrollView.contentOffset.x),
@"y": @(scrollView.contentOffset.y)
},
@"contentInset": @{
@"top": @(_scrollView.contentInset.top),
@"left": @(_scrollView.contentInset.left),
@"bottom": @(_scrollView.contentInset.bottom),
@"right": @(_scrollView.contentInset.right)
},
@"contentSize": @{
@"width": @(_scrollView.contentSize.width),
@"height": @(_scrollView.contentSize.height)
},
@"layoutMeasurement": @{
@"width": @(_scrollView.frame.size.width),
@"height": @(_scrollView.frame.size.height)
},
@"zoomScale": @(_scrollView.zoomScale ?: 1),
});
}
}

@end
@@ -38,6 +38,7 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onContentSizeChange, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onTextInput, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(placeholder, NSString)
RCT_EXPORT_VIEW_PROPERTY(placeholderTextColor, UIColor)

0 comments on commit c609aee

Please sign in to comment.