Fixed onFocus/onBlur events for multiline TextInput

Summary: public

onFocus and onBlur were not firing for multiline TextInputs.

Reviewed By: tadeuzagallo

Differential Revision: D2699846

fb-gh-sync-id: 7e64309bc631a42a99f989f615fef927dc50217c
This commit is contained in:
Nick Lockwood 2015-11-27 06:52:29 -08:00 committed by facebook-github-bot-0
parent 60db876f66
commit 01a0facf33
3 changed files with 87 additions and 74 deletions

View File

@ -301,50 +301,6 @@ exports.displayName = (undefined: ?string);
exports.title = '<TextInput>'; exports.title = '<TextInput>';
exports.description = 'Single and multi-line text inputs.'; exports.description = 'Single and multi-line text inputs.';
exports.examples = [ exports.examples = [
{
title: 'Multiline',
render: function() {
return (
<View>
<TextInput
placeholder="multiline text input"
multiline={true}
style={styles.multiline}
/>
<TextInput
placeholder="multiline text input with font styles and placeholder"
multiline={true}
clearTextOnFocus={true}
autoCorrect={true}
autoCapitalize="words"
placeholderTextColor="red"
keyboardType="url"
style={[styles.multiline, styles.multilineWithFontStyles]}
/>
<TextInput
placeholder="uneditable multiline text input"
editable={false}
multiline={true}
style={styles.multiline}
/>
<TextInput
placeholder="multiline with children"
multiline={true}
enablesReturnKeyAutomatically={true}
returnKeyType="go"
style={styles.multiline}>
<View style={styles.multilineChild}/>
</TextInput>
</View>
);
}
},
{
title: 'Attributed text',
render: function() {
return <TokenizedTextExample />;
}
},
{ {
title: 'Auto-focus', title: 'Auto-focus',
render: function() { render: function() {
@ -592,4 +548,48 @@ exports.examples = [
title: 'Blur on submit', title: 'Blur on submit',
render: function(): ReactElement { return <BlurOnSubmitExample />; }, render: function(): ReactElement { return <BlurOnSubmitExample />; },
}, },
{
title: 'Multiline',
render: function() {
return (
<View>
<TextInput
placeholder="multiline text input"
multiline={true}
style={styles.multiline}
/>
<TextInput
placeholder="multiline text input with font styles and placeholder"
multiline={true}
clearTextOnFocus={true}
autoCorrect={true}
autoCapitalize="words"
placeholderTextColor="red"
keyboardType="url"
style={[styles.multiline, styles.multilineWithFontStyles]}
/>
<TextInput
placeholder="uneditable multiline text input"
editable={false}
multiline={true}
style={styles.multiline}
/>
<TextInput
placeholder="multiline with children"
multiline={true}
enablesReturnKeyAutomatically={true}
returnKeyType="go"
style={styles.multiline}>
<View style={styles.multilineChild}/>
</TextInput>
</View>
);
}
},
{
title: 'Attributed text',
render: function() {
return <TokenizedTextExample />;
}
},
]; ];

View File

@ -239,12 +239,19 @@ static void RCTUpdatePlaceholder(RCTTextField *self)
} }
} }
- (BOOL)becomeFirstResponder - (void)reactWillMakeFirstResponder
{ {
_jsRequestingFirstResponder = YES; _jsRequestingFirstResponder = YES;
BOOL result = [super becomeFirstResponder]; }
- (void)reactDidMakeFirstResponder
{
_jsRequestingFirstResponder = NO; _jsRequestingFirstResponder = NO;
return result; }
- (BOOL)canBecomeFirstResponder
{
return _jsRequestingFirstResponder;
} }
- (BOOL)resignFirstResponder - (BOOL)resignFirstResponder
@ -261,9 +268,4 @@ static void RCTUpdatePlaceholder(RCTTextField *self)
return result; return result;
} }
- (BOOL)canBecomeFirstResponder
{
return _jsRequestingFirstResponder;
}
@end @end

View File

@ -22,6 +22,9 @@
@end @end
@implementation RCTUITextView @implementation RCTUITextView
{
BOOL _jsRequestingFirstResponder;
}
- (void)paste:(id)sender - (void)paste:(id)sender
{ {
@ -29,12 +32,26 @@
[super paste:sender]; [super paste:sender];
} }
- (void)reactWillMakeFirstResponder
{
_jsRequestingFirstResponder = YES;
}
- (BOOL)canBecomeFirstResponder
{
return _jsRequestingFirstResponder;
}
- (void)reactDidMakeFirstResponder
{
_jsRequestingFirstResponder = NO;
}
@end @end
@implementation RCTTextView @implementation RCTTextView
{ {
RCTEventDispatcher *_eventDispatcher; RCTEventDispatcher *_eventDispatcher;
BOOL _jsRequestingFirstResponder;
NSString *_placeholder; NSString *_placeholder;
UITextView *_placeholderView; UITextView *_placeholderView;
UITextView *_textView; UITextView *_textView;
@ -360,7 +377,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeFocus [_eventDispatcher sendTextEventWithType:RCTTextEventTypeFocus
reactTag:self.reactTag reactTag:self.reactTag
text:textView.text text:nil
key:nil key:nil
eventCount:_nativeEventCount]; eventCount:_nativeEventCount];
} }
@ -385,28 +402,27 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
text:textView.text text:textView.text
key:nil key:nil
eventCount:_nativeEventCount]; eventCount:_nativeEventCount];
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeBlur
reactTag:self.reactTag
text:nil
key:nil
eventCount:_nativeEventCount];
}
- (void)reactWillMakeFirstResponder
{
[_textView reactWillMakeFirstResponder];
} }
- (BOOL)becomeFirstResponder - (BOOL)becomeFirstResponder
{ {
_jsRequestingFirstResponder = YES; return [_textView becomeFirstResponder];
BOOL result = [_textView becomeFirstResponder];
_jsRequestingFirstResponder = NO;
return result;
} }
- (BOOL)resignFirstResponder - (void)reactDidMakeFirstResponder
{ {
[super resignFirstResponder]; [_textView reactDidMakeFirstResponder];
BOOL result = [_textView resignFirstResponder];
if (result) {
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeBlur
reactTag:self.reactTag
text:_textView.text
key:nil
eventCount:_nativeEventCount];
}
return result;
} }
- (void)layoutSubviews - (void)layoutSubviews
@ -415,11 +431,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
[self updateFrames]; [self updateFrames];
} }
- (BOOL)canBecomeFirstResponder
{
return _jsRequestingFirstResponder;
}
- (UIFont *)defaultPlaceholderFont - (UIFont *)defaultPlaceholderFont
{ {
return [UIFont systemFontOfSize:17]; return [UIFont systemFontOfSize:17];