Skip to content
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

Conversation

OlimpiaZurek
Copy link

@OlimpiaZurek OlimpiaZurek commented Apr 28, 2023

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 and caretYOffset props to TextInput component

Test Plan:

Default caret:

default_caret.mov

Caret with caretHeight and caretYOffsetadjustment:

adjusting_caret.mov

@facebook-github-bot
Copy link
Contributor

Hi @OlimpiaZurek!

Thank you for your pull request and welcome to our community.

Action Required

In 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.

Process

In 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 CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at [email protected]. Thanks!

@analysis-bot
Copy link

analysis-bot commented Apr 28, 2023

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 18,000,725 +118,595
android hermes armeabi-v7a n/a --
android hermes x86 n/a --
android hermes x86_64 n/a --
android jsc arm64-v8a 21,359,082 +118,511
android jsc armeabi-v7a n/a --
android jsc x86 n/a --
android jsc x86_64 n/a --

Base commit: 12f2c3c
Branch: main

@facebook-github-bot
Copy link
Contributor

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 28, 2023
Copy link
Contributor

@fabioh8010 fabioh8010 left a 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:

  1. 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.
  2. 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.

@OlimpiaZurek OlimpiaZurek changed the title feat: add caretHeight and caretYoffset to TextInput component feat: [iOS] add caretHeight and caretYoffset to TextInput component May 4, 2023
@OlimpiaZurek OlimpiaZurek force-pushed the feature/text-input-ios-support-for-adjusting-caret branch from e265c13 to 2cbd5a3 Compare May 4, 2023 09:55
@OlimpiaZurek
Copy link
Author

All comments have already been resolved. Can someone take another look and review? Thanks!

@koko57
Copy link
Contributor

koko57 commented Jun 16, 2023

Conflicts resolved, ready for review

@sakluger
Copy link

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!

@fabioh8010
Copy link
Contributor

Hi @sakluger , I don't work at Meta, I just reviewed because I'm from the same company of the PR author.

@cpojer
Copy link
Contributor

cpojer commented Jan 30, 2024

@sammy-SC @yungsters could you merge this?

@implementation CustomTextSelectionRect

- (CGRect)rect {
return __rect;
Copy link
Contributor

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?

Copy link
Author

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) {
Copy link
Contributor

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?

Copy link
Author

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 {
Copy link
Contributor

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.

Copy link
Author

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:
Screenshot 2024-02-26 at 09 42 32

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.

Copy link
Member

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?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, here is a screenshot for multi-line text selection:

Screenshot 2024-04-05 at 13 07 49

@OlimpiaZurek OlimpiaZurek force-pushed the feature/text-input-ios-support-for-adjusting-caret branch from bd5c769 to f55a9ff Compare February 23, 2024 12:44
@OlimpiaZurek
Copy link
Author

@sammy-SC All comments have been resolved. Can you take a look and review ? Thanks!
cc: @NickGerleman

@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Apr 2, 2024
@javache
Copy link
Member

javache commented Apr 2, 2024

LGTM, few comments.

return originalRect;
}

- (NSArray *)selectionRectsForRange:(UITextRange *)range {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- (NSArray *)selectionRectsForRange:(UITextRange *)range {
- (NSArray<UITextSelectionRect *> *)selectionRectsForRange:(UITextRange *)range {

Copy link
Author

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
Copy link
Member

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

Suggested change
@interface CustomTextSelectionRect : UITextSelectionRect
@interface RCTTextSelectionRect : UITextSelectionRect

Copy link
Author

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 {
Copy link
Member

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) {
Copy link
Member

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?

Copy link
Author

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);
Copy link
Member

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.

Copy link
Author

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.

@OlimpiaZurek OlimpiaZurek requested review from javache and sammy-SC April 5, 2024 11:09
@react-native-bot
Copy link
Collaborator

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.

@react-native-bot react-native-bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Oct 3, 2024
@react-native-bot
Copy link
Collaborator

This PR was closed because it has been stalled for 7 days with no activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants