From f73464851b734f770754b6efbd30df72d5bd1aac Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 1 May 2017 21:05:38 -0700 Subject: [PATCH] Revert D4680300: [RN] BREAKING: Better TextInput: `contentSize` property was removed from `.onChange` event. Differential Revision: D4680300 fbshipit-source-id: 20f7299c53cc54215fb333e97d7e11de087e303d --- Libraries/Text/RCTTextView.m | 29 +++++++++++++++++++ .../textinput/ReactTextChangedEvent.java | 12 ++++++++ .../textinput/ReactTextInputManager.java | 14 +++++++++ 3 files changed, 55 insertions(+) diff --git a/Libraries/Text/RCTTextView.m b/Libraries/Text/RCTTextView.m index 6b2880eff..f4329d0ef 100644 --- a/Libraries/Text/RCTTextView.m +++ b/Libraries/Text/RCTTextView.m @@ -489,6 +489,35 @@ static BOOL findMismatch(NSString *first, NSString *second, NSRange *firstRange, _nativeUpdatesInFlight = NO; _nativeEventCount++; + + // TODO: t16435709 This part will be removed soon. + if (!self.reactTag || !_onChange) { + return; + } + + // When the context size increases, iOS updates the contentSize twice; once + // with a lower height, then again with the correct height. To prevent a + // spurious event from being sent, we track the previous, and only send the + // update event if it matches our expectation that greater text length + // should result in increased height. This assumption is, of course, not + // necessarily true because shorter text might include more linebreaks, but + // in practice this works well enough. + NSUInteger textLength = textView.text.length; + CGFloat contentHeight = textView.contentSize.height; + if (textLength >= _previousTextLength) { + contentHeight = MAX(contentHeight, _previousContentHeight); + } + _previousTextLength = textLength; + _previousContentHeight = contentHeight; + _onChange(@{ + @"text": self.text, + @"contentSize": @{ + @"height": @(contentHeight), + @"width": @(textView.contentSize.width) + }, + @"target": self.reactTag, + @"eventCount": @(_nativeEventCount), + }); } - (void)textViewDidEndEditing:(UITextView *)textView diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.java index 7b9f2829b..67ca37c5e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextChangedEvent.java @@ -23,14 +23,20 @@ public class ReactTextChangedEvent extends Event { public static final String EVENT_NAME = "topChange"; private String mText; + private float mContentWidth; + private float mContentHeight; private int mEventCount; public ReactTextChangedEvent( int viewId, String text, + float contentSizeWidth, + float contentSizeHeight, int eventCount) { super(viewId); mText = text; + mContentWidth = contentSizeWidth; + mContentHeight = contentSizeHeight; mEventCount = eventCount; } @@ -47,7 +53,13 @@ public class ReactTextChangedEvent extends Event { private WritableMap serializeEventData() { WritableMap eventData = Arguments.createMap(); eventData.putString("text", mText); + + WritableMap contentSize = Arguments.createMap(); + contentSize.putDouble("width", mContentWidth); + contentSize.putDouble("height", mContentHeight); + eventData.putMap("contentSize", contentSize); eventData.putInt("eventCount", mEventCount); + eventData.putInt("target", getViewTag()); return eventData; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 24189fc4e..c464ec528 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -683,12 +683,26 @@ public class ReactTextInputManager extends BaseViewManager