-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TextInput - Multiline] Reimplemented RCTTextView and added auto height scaling. #1229
Conversation
… auto height scaling to RCTTextView.
@lukasreichart - really interesting stuff! Curious what @nicklockwood has to say about it |
Wow this looks great.
Why is this? |
Also cc @a2 |
Anything preventing this one from being merged? It's much needed functionality for TextInput, but this PR has been pretty quiet the last month. |
…lso working correctly with the calculation of the height.
@sjmueller I am waiting for the review of @a2 .... |
cool, guys 🍺 |
@brentvatne @ide @a2 @nicklockwood any progress here? 👍 |
👍 |
Unfortunately not @lukasreichart - I think we just need to hold up until someone has time to properly review :( |
Sorry for the delay. It's a complex PR, so it will take a couple of days of somebody's time to review and test, and we're a small team with a long task list :-) We'll get to it eventually though. |
👍 Hope this gets merged soon. While not road-block, it is a monumental task to implement similar behaviors otherwise 😦 |
Hi just want to echo that this is a really key feature! |
@nicklockwood I just noticed, that have you have rewritten some of the RCTText and RCTTextView code since I've created this PR. I could rewrite my PR so it would be easier to merge for you. Would this help? I really want to close this, because this feature makes working with text so much easier. |
+1 |
@lukasreichart it would be awesome if you could rewrite the PR. Many of us are using your changes manually, and it would be great to have a version that works with the latest build of RN. |
Any move on this? |
Hey, really sorry for the radio silence on this. It is an important feature, but as you say we now have two competing solutions, both of which are very complex to review, and it affects a critical component used in most of our apps. I haven't forgotten about this, and I'll try to get one or other solution merged in the near future. |
👍 Thanks @nicklockwood! |
greate On Thu, Nov 26, 2015 at 7:59 PM, Christopher Dro notifications@github.com
|
Are there any updates to this or PR #3097? We would really like to see this functionality merged in :) |
+1 |
@cgilboy - as mentioned above, Nick is working on it! There's truly no better person to have on the job, so it's in good hands :) |
+1 for merge, please. |
+1 for merge |
@martincik @sebglazebrook @kinhunt @cgilboy - you can show your support for it here: https://productpains.com/#!/post/react-native/add-support-for-automatically-resizing-multiline-textinput-based-on-content/ |
hows this going? any plan to merge/ work on this PR soon? |
Summary: public This diff adds support for auto-resizing multiline text fields. This has been a long-requested feature, with several native solutions having been proposed (see #1229 and D2846915). Rather than making this a feature of the native component, this diff simply exposes some extra information in the `onChange` event that makes it easy to implement this in pure JS code. I think this is preferable, since it's simpler, works cross-platform, and avoids any controversy about what the API should look like, or how the props should be named. It also makes it easier to implement custom min/max-height logic. Reviewed By: sahrens Differential Revision: D2849889 fb-gh-sync-id: d9ddf4ba4037d388dac0558aa467d958300aa691
Sorry for the long silence on this. At the time this PR was created, calculating the text layout on the shadow queue made a lot of sense, but now that RCTTextView is making heavy use of the scrollview.contentSize anyway, there's not really any performance gain to doing this work in the background, and it massively increases the complexity. I did try rebasing this against the latest codebase, but it seems to be broken in a way that I can't fix, and in light of the much simpler solution I've implemented in 481f560, I'm not sure it's worth trying to revive this. Thanks for all your efforts, and sorry we didn't manage to make this work. |
Summary: public This diff adds support for auto-resizing multiline text fields. This has been a long-requested feature, with several native solutions having been proposed (see facebook#1229 and D2846915). Rather than making this a feature of the native component, this diff simply exposes some extra information in the `onChange` event that makes it easy to implement this in pure JS code. I think this is preferable, since it's simpler, works cross-platform, and avoids any controversy about what the API should look like, or how the props should be named. It also makes it easier to implement custom min/max-height logic. Reviewed By: sahrens Differential Revision: D2849889 fb-gh-sync-id: d9ddf4ba4037d388dac0558aa467d958300aa691
Summary: public This diff adds support for auto-resizing multiline text fields. This has been a long-requested feature, with several native solutions having been proposed (see facebook#1229 and D2846915). Rather than making this a feature of the native component, this diff simply exposes some extra information in the `onChange` event that makes it easy to implement this in pure JS code. I think this is preferable, since it's simpler, works cross-platform, and avoids any controversy about what the API should look like, or how the props should be named. It also makes it easier to implement custom min/max-height logic. Reviewed By: sahrens Differential Revision: D2849889 fb-gh-sync-id: d9ddf4ba4037d388dac0558aa467d958300aa691
Hey @nicklockwood, quick question - the onChange event that we depend upon here only fires when a user enters text via a keyboard. This means that if there is more than one line of text loaded in (e.g. resuming a form), the height will be restricted to whatever the default is. Is there any way to trigger (or measure) the contentSize so that we can set an accurate initial height? |
Great point @deanmcpherson, I'm also curious about this |
So I've have had a go at firing the same onChange event in the updateContentSize method of I did have a go at creating a separate event name to listen on for inputs, (e.g. onContentSize) but couldn't quite get it to come through correctly. Though I imagine throwing in custom events isn't really a great way forward either. Thoughts @nicklockwood @brentvatne? |
What we ideally want here is to:
The former can be ensured by only firing onChange in one place. The latter can be ensured by keeping track of the previous contentSize, text, etc. and comparing them before firing the event. If you have a solution that seems to work, put up a PR and we can review it and suggest changes if needed. |
Thanks @nicklockwood! @deanmcpherson - do you want to try to PR this suggested approach? @mkonicek we need something similar for Android too |
I've noticed a few instances where my implementation isn't working, in particular using @nicklockwood do you think it makes sense for onChange to fire when no text value has changed? For most uses of |
I agree it's not ideal, but it's the least bad option I can think of, and according to @dmmiller that's how it works on Android currently (unless I misunderstood?) |
What we should probably do is add a separate onChangeContentSize event which can be observerved independently of onTextChange. Let's get the APIs consistent between platforms before we start changing them though. |
For auto-resizing of multiline TextInput use ,
|
Thanks for the hot update!
…rn/parse-url-6.0.2 Bump parse-url from 6.0.0 to 6.0.2
I started with the goal to add auto height scaling functionality to the
RCTTextView
class. As discussed in this thread.I soon noticed, that I would have to rewrite most of
RCTTextView
and create at least an object on the shadow thread for it:RCTShadowTextView
.I tried to implement the
RCTShadowTextView
the same way asRCTShadowText
, so there is as much consistency as possible. I did not change the interface of the currentRCTTextView
implementation, so there shouldn't be any problems with updating an existing application.Implemented auto height scaling for TextView
The RCTShadowTextView class implements the Measure function of css-layout. If the TextInput componenet does not have a specified height, it will automatically scale to the height that matches the text. It calculates the height using
NSLayoutContaniner
becauseUITextView
is not thread safe.Note: It's important to disable scrolling when using the auto scaling.
Data Flow
The displayed text is sent from JS to the object on the Shadow Thread. The shadow object is responsible for generating a
NSAttributedString
(Same approach as inRCTShadowText
).Updates from javascript go the following way:
JS Object --(
NSString
)-->RCTShadowTextView
--(NSAttributedString
)-->RCTShadowText
Updates from
UITextView
go the following way:RCTShadowText
--(Event)--> JS Object --(NSString
)-->RCTShadowTextView
Please note that the update chain stops after
RCTShadowTextView
. This way theUITextView
is only updated when we change something from javascript, but not if the user types somehting into theUITextView
. In this case we only update the Shadow object. This approach is necessary because we can not constantly reset theUITextView.attributedText
property, because this will also remove any autocorrections.Created the RCTAttributedStringHandler class
The
RCTAttributedStringHandler
stores text styling attributes. It can be used to generate a styledNSAttributedString
from aNSString
.The process of generating the
NSAttributedString
was pretty much copied fromRCTShadowText
. The reason why I moved it into a separate object is, thatRCTShadowTextView
needs to store text attributes for two different Strings. The text string and the placeholder string. (Although they share most of the attributes, the approach to move this functionality into a separate object is much cleaner).Rewrote the uiBlockToAmendWithShadowRegistry
Rewrote the
(RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(RCTSparseArray *)shadowViewRegistry
function ofRCTTextManager
andRCTTextViewManager
, so thatRCTShadowText
andRCTShadowTextView
are both able to use thetextLifecycle
variable ofRCTShadowView
.Small Additions / Notes
if (node.children.length === 0) { return; }
. This may also be the first step to be able to embed text nodes.Any additions and questions are welcome. 👍