-
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
feat: [iOS] add caretHeight and caretYoffset to TextInput component #37147
feat: [iOS] add caretHeight and caretYoffset to TextInput component #37147
Conversation
Hi @OlimpiaZurek! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at [email protected]. Thanks! |
Base commit: 12f2c3c |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @OlimpiaZurek ! I reviewed your code and left some comments, minor things I just noticed. Besides that, I have two other points:
- Please include a Test Plan in your PR. For example, you could attach a video showing you how your props works in the text input for iOS.
- Also create a PR to include your props in the react-native-website repo. You can link each issue to the other to keep track of the overall progress.
packages/react-native/Libraries/Components/TextInput/TextInput.flow.js
Outdated
Show resolved
Hide resolved
packages/react-native/Libraries/Components/TextInput/TextInput.js
Outdated
Show resolved
Hide resolved
packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.m
Outdated
Show resolved
Hide resolved
packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.m
Outdated
Show resolved
Hide resolved
...nderer/components/textinput/iostextinput/react/renderer/components/iostextinput/primitives.h
Outdated
Show resolved
Hide resolved
e265c13
to
2cbd5a3
Compare
All comments have already been resolved. Can someone take another look and review? Thanks! |
caefbb8
to
5e48d26
Compare
Conflicts resolved, ready for review |
Hey @fabioh8010 - would it be possible to add this PR to your list of priorities? It's one of our oldest outstanding bugs and we'd love to get it resolved. Thanks! |
Hi @sakluger , I don't work at Meta, I just reviewed because I'm from the same company of the PR author. |
@sammy-SC @yungsters could you merge this? |
@implementation CustomTextSelectionRect | ||
|
||
- (CGRect)rect { | ||
return __rect; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are there two underscores before member variables?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used double underscores to avoid name collisions. Changed implementation a bit and removed them.
|
||
- (NSArray *)selectionRectsForRange:(UITextRange *)range { | ||
NSArray *superRects = [super selectionRectsForRange:range]; | ||
if(_caretYOffset != 0 && _caretHeight != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if only _caretYOffset is set? Shouldn't the below block be executed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The block should only be executed if both properties are set.
return originalRect; | ||
} | ||
|
||
- (NSArray *)selectionRectsForRange:(UITextRange *)range { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this override needed? I don't understand what it is trying to achieve on top of handling _caretYOffset
and _caretHeight
in the method caretRectForPosition
above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal is to avoid the cursor touching the the symbols of the previous line in the second and subsequent lines:
This is the default behavior derived from caretRectForPosition
. To fix this, I added two new properties _caretYOffset
and _caretHeight
to calculate the caret position and caret height, thus preventing the cursor from overlapping the previous line of text.
To keep the same effect on selection selectionRectsForRange
needs to be override as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a screenshot of what this looks like with a multi-line text selection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bd5c769
to
f55a9ff
Compare
@sammy-SC All comments have been resolved. Can you take a look and review ? Thanks! |
LGTM, few comments. |
return originalRect; | ||
} | ||
|
||
- (NSArray *)selectionRectsForRange:(UITextRange *)range { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- (NSArray *)selectionRectsForRange:(UITextRange *)range { | |
- (NSArray<UITextSelectionRect *> *)selectionRectsForRange:(UITextRange *)range { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
@@ -13,6 +13,33 @@ | |||
#import <React/RCTBackedTextInputDelegateAdapter.h> | |||
#import <React/RCTTextAttributes.h> | |||
|
|||
//the UITextSelectionRect subclass needs to be created because the original version is not writable | |||
@interface CustomTextSelectionRect : UITextSelectionRect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UITextSelectionRect is explicitly documented as being an abstract base class so this makes sense. Maybe mention that instead of it not being writable?
Use RCT
as prefix
@interface CustomTextSelectionRect : UITextSelectionRect | |
@interface RCTTextSelectionRect : UITextSelectionRect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, changed
return originalRect; | ||
} | ||
|
||
- (NSArray *)selectionRectsForRange:(UITextRange *)range { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a screenshot of what this looks like with a multi-line text selection?
|
||
- (NSArray *)selectionRectsForRange:(UITextRange *)range { | ||
NSArray *superRects = [super selectionRectsForRange:range]; | ||
if(_caretYOffset != 0 && _caretHeight != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be ||
, so this works if you specify either one of the properties?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The block should only be executed if both properties are set.
for (UITextSelectionRect *rect in superRects) { | ||
CustomTextSelectionRect *customTextRect = [[CustomTextSelectionRect alloc] init]; | ||
|
||
customTextRect.rect = CGRectMake(rect.rect.origin.x, rect.rect.origin.y + _caretYOffset, rect.rect.size.width, _caretHeight); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This then needs to handle _caretHeight
being potentially 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The block should only be executed if both properties are set.
This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
This PR was closed because it has been stalled for 7 days with no activity. |
Summary:
This PR adds support for the caret height and caret position properties in iOS multi-line TextInput
PR for the docs update: facebook/react-native-website#3709
Changelog:
[IOS] [ADDED] - Add
caretHeight
andcaretYOffset
props to TextInput componentTest Plan:
Default caret:
default_caret.mov
Caret with
caretHeight
andcaretYOffset
adjustment:adjusting_caret.mov