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.