Does anyone have any ideas on how to get the caret position of a TextInput
? I tried onSelectionChange
and creating an event emitter from DocumentSelectionState
but neither appear to be working (they don't fire anything, no matter what I select).
有没有人对如何获得TextInput的插入位置有任何想法?我尝试了onSelectionChange并从DocumentSelectionState创建一个事件发射器,但似乎都没有工作(无论我选择什么,它们都不会触发任何东西)。
For Example: https://rnplay.org/apps/eZnvIA
例如:https://rnplay.org/apps/eZnvIA
3 个解决方案
#1
11
onSelectionChange={(event) => console.log(event.nativeEvent.selection)}
#2
1
If you're willing to get semi-adventurous, you can update the react-native
library to allow retrieving the cursor (x/y) coordinates (relative to the TextInput
), in the onSelectionChange
event parameter.
如果您愿意进行半冒险,可以更新react-native库以允许在onSelectionChange事件参数中检索光标(x / y)坐标(相对于TextInput)。
Full instructions for IOS AND Android. (Disclaimer: I did not come up with this solution)
IOS和Android的完整说明。 (免责声明:我没有提出这个解决方案)
TLDR - IOS + ReactNative 0.49.1
node_modules/react-native/Libraries/Text/RCTTextSelection.h
/**
* Object containing information about a TextInput's selection.
*/
@interface RCTTextSelection : NSObject
@property (nonatomic, assign, readonly) NSInteger start;
@property (nonatomic, assign, readonly) NSInteger end;
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
@property (nonatomic, assign, readonly) CGPoint cursorPosition;
- (instancetype)initWithStart:(NSInteger)start end:(NSInteger)end cursorPosition:(CGPoint)cursorPosition;
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
@end
node_modules/react-native/Libraries/Text/RCTTextSelection.m
@implementation RCTTextSelection
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
- (instancetype)initWithStart:(NSInteger)start end:(NSInteger)end cursorPosition:(CGPoint)cursorPosition
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
{
if (self = [super init]) {
_start = start;
_end = end;
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
_cursorPosition = cursorPosition;
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
}
return self;
}
@end
@implementation RCTConvert (RCTTextSelection)
+ (RCTTextSelection *)RCTTextSelection:(id)json
{
if ([json isKindOfClass:[NSDictionary class]]) {
NSInteger start = [self NSInteger:json[@"start"]];
NSInteger end = [self NSInteger:json[@"end"]];
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
CGPoint cursorPosition = CGPointMake(
[self CGFloat:json[@"cursorPositionX"]],
[self CGFloat:json[@"cursorPositionY"]]
);
return [[RCTTextSelection alloc] initWithStart:start
end:end
cursorPosition:cursorPosition];
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
}
return nil;
}
@end
node_modules/react-native/Libraries/Text/RCTTextInput.m
- (RCTTextSelection *)selection
{
id<RCTBackedTextInputViewProtocol> backedTextInput = self.backedTextInputView;
UITextRange *selectedTextRange = backedTextInput.selectedTextRange;
return [[RCTTextSelection new] initWithStart:[backedTextInput offsetFromPosition:backedTextInput.beginningOfDocument toPosition:selectedTextRange.start]
end:[backedTextInput offsetFromPosition:backedTextInput.beginningOfDocument toPosition:selectedTextRange.end]
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
cursorPosition:[backedTextInput caretRectForPosition:selectedTextRange.start].origin];
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
}
...
- (void)textInputDidChangeSelection
{
if (!_onSelectionChange) {
return;
}
RCTTextSelection *selection = self.selection;
_onSelectionChange(@{
@"selection": @{
@"start": @(selection.start),
@"end": @(selection.end),
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
@"cursorPositionX": @(selection.cursorPosition.x),
@"cursorPositionY": @(selection.cursorPosition.y)
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
},
});
}
#3
-4
As a start, you probably want to use the onChange or even onChangeText event instead. That will get your alert firing.
首先,您可能希望使用onChange或甚至onChangeText事件。这将使你的警报开火。
#1
11
onSelectionChange={(event) => console.log(event.nativeEvent.selection)}
#2
1
If you're willing to get semi-adventurous, you can update the react-native
library to allow retrieving the cursor (x/y) coordinates (relative to the TextInput
), in the onSelectionChange
event parameter.
如果您愿意进行半冒险,可以更新react-native库以允许在onSelectionChange事件参数中检索光标(x / y)坐标(相对于TextInput)。
Full instructions for IOS AND Android. (Disclaimer: I did not come up with this solution)
IOS和Android的完整说明。 (免责声明:我没有提出这个解决方案)
TLDR - IOS + ReactNative 0.49.1
node_modules/react-native/Libraries/Text/RCTTextSelection.h
/**
* Object containing information about a TextInput's selection.
*/
@interface RCTTextSelection : NSObject
@property (nonatomic, assign, readonly) NSInteger start;
@property (nonatomic, assign, readonly) NSInteger end;
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
@property (nonatomic, assign, readonly) CGPoint cursorPosition;
- (instancetype)initWithStart:(NSInteger)start end:(NSInteger)end cursorPosition:(CGPoint)cursorPosition;
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
@end
node_modules/react-native/Libraries/Text/RCTTextSelection.m
@implementation RCTTextSelection
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
- (instancetype)initWithStart:(NSInteger)start end:(NSInteger)end cursorPosition:(CGPoint)cursorPosition
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
{
if (self = [super init]) {
_start = start;
_end = end;
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
_cursorPosition = cursorPosition;
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
}
return self;
}
@end
@implementation RCTConvert (RCTTextSelection)
+ (RCTTextSelection *)RCTTextSelection:(id)json
{
if ([json isKindOfClass:[NSDictionary class]]) {
NSInteger start = [self NSInteger:json[@"start"]];
NSInteger end = [self NSInteger:json[@"end"]];
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
CGPoint cursorPosition = CGPointMake(
[self CGFloat:json[@"cursorPositionX"]],
[self CGFloat:json[@"cursorPositionY"]]
);
return [[RCTTextSelection alloc] initWithStart:start
end:end
cursorPosition:cursorPosition];
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
}
return nil;
}
@end
node_modules/react-native/Libraries/Text/RCTTextInput.m
- (RCTTextSelection *)selection
{
id<RCTBackedTextInputViewProtocol> backedTextInput = self.backedTextInputView;
UITextRange *selectedTextRange = backedTextInput.selectedTextRange;
return [[RCTTextSelection new] initWithStart:[backedTextInput offsetFromPosition:backedTextInput.beginningOfDocument toPosition:selectedTextRange.start]
end:[backedTextInput offsetFromPosition:backedTextInput.beginningOfDocument toPosition:selectedTextRange.end]
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
cursorPosition:[backedTextInput caretRectForPosition:selectedTextRange.start].origin];
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
}
...
- (void)textInputDidChangeSelection
{
if (!_onSelectionChange) {
return;
}
RCTTextSelection *selection = self.selection;
_onSelectionChange(@{
@"selection": @{
@"start": @(selection.start),
@"end": @(selection.end),
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
@"cursorPositionX": @(selection.cursorPosition.x),
@"cursorPositionY": @(selection.cursorPosition.y)
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
},
});
}
#3
-4
As a start, you probably want to use the onChange or even onChangeText event instead. That will get your alert firing.
首先,您可能希望使用onChange或甚至onChangeText事件。这将使你的警报开火。