Skip to content

Commit

Permalink
feat(ios): add paragraph styles support for TextInput
Browse files Browse the repository at this point in the history
TextInput Current support:
1.lineHeight
2.lineSpacing
3.lineHeightMultiple
  • Loading branch information
wwwcg committed Jun 17, 2024
1 parent 0e06849 commit 33184a2
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 5 deletions.
6 changes: 5 additions & 1 deletion examples/hippy-react-demo/src/components/TextInput/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ const styles = StyleSheet.create({
fontSize: 16,
color: '#242424',
height: 30,
lineHeight: 30,
// you can use lineHeight/lineSpacing/lineHeightMultiple
// to control the space between lines in multi-line input.(iOS only for now)
// lineHeight: 100,
// lineSpacing: 50,
lineHeightMultiple: 1.5,
},
input_style_block: {
height: 100,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ export default {
underline-color-android: #40b883;
placeholder-text-color: #666;
align-self: center;
/* you can use line-height/line-spacing/line-height-multiple */
/* to control the space between lines in multi-line input. (iOS only for now) */
line-height: 30;
/*line-spacing: 20;*/
/*line-height-multiple: 1.5;*/
}
#demo-textarea .output {
Expand Down
8 changes: 8 additions & 0 deletions ios/sdk/component/textinput/HippyShadowTextView.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,12 @@
@property (nonatomic, copy) NSString *placeholder;

@property (nonatomic, strong) UIFont *font;

/// ParagraphStyles - lineHeight
@property (nonatomic, strong) NSNumber *lineHeight;
/// ParagraphStyles - lineSpacing
@property (nonatomic, strong) NSNumber *lineSpacing;
/// ParagraphStyles - lineHeightMultiple
@property (nonatomic, strong) NSNumber *lineHeightMultiple;

@end
21 changes: 20 additions & 1 deletion ios/sdk/component/textinput/HippyShadowTextView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,26 @@ static MTTSize x5MeasureFunc(
if (shadowText.font == nil) {
shadowText.font = [UIFont systemFontOfSize:16];
}
shadowText.dicAttributes = @ { NSFontAttributeName: shadowText.font };
NSDictionary *attrs = nil;
if ((id)shadowText.lineHeight != nil ||
(id)shadowText.lineSpacing != nil ||
(id)shadowText.lineHeightMultiple != nil) {
// Add paragraphStyle
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
if ((id)shadowText.lineHeight != nil) {
paragraphStyle.minimumLineHeight = [shadowText.lineHeight doubleValue];
paragraphStyle.maximumLineHeight = [shadowText.lineHeight doubleValue];
} else if ((id)shadowText.lineSpacing != nil) {
paragraphStyle.lineSpacing = [shadowText.lineSpacing doubleValue];
} else if ((id)shadowText.lineHeightMultiple != nil) {
paragraphStyle.lineHeightMultiple = [shadowText.lineHeightMultiple doubleValue];
}
attrs = @{ NSFontAttributeName: shadowText.font,
NSParagraphStyleAttributeName : paragraphStyle };
} else {
attrs = @{ NSFontAttributeName: shadowText.font };
}
shadowText.dicAttributes = attrs;
}
CGSize computedSize = [text sizeWithAttributes:shadowText.dicAttributes];
MTTSize result;
Expand Down
7 changes: 7 additions & 0 deletions ios/sdk/component/textinput/HippyTextField.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,11 @@
@property (nonatomic, copy) NSString *text;
@property (nonatomic, strong) UIColor *textColor;

/// ParagraphStyles - lineHeight
@property (nonatomic, strong) NSNumber *lineHeight;
/// ParagraphStyles - lineSpacing
@property (nonatomic, strong) NSNumber *lineSpacing;
/// ParagraphStyles - lineHeightMultiple
@property (nonatomic, strong) NSNumber *lineHeightMultiple;

@end
19 changes: 19 additions & 0 deletions ios/sdk/component/textinput/HippyTextField.m
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ @implementation HippyTextField {
HippyUITextField *_textView;
}

@dynamic lineHeight;
@dynamic lineSpacing;
@dynamic lineHeightMultiple;

- (void)keyboardWillShow:(NSNotification *)aNotification {
[super keyboardWillShow:aNotification];
NSDictionary *userInfo = [aNotification userInfo];
Expand Down Expand Up @@ -438,4 +442,19 @@ - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRang
return YES;
}


#pragma mark - LineHeight Related

- (void)setLineHeight:(NSNumber *)lineHeight {
// LineHeight does not take effect on single-line input.
}

- (void)setLineSpacing:(NSNumber *)lineSpacing {
// LineSpacing does not take effect on single-line input.
}

- (void)setLineHeightMultiple:(NSNumber *)lineHeightMultiple {
// LineHeightMultiple does not take effect on single-line input.
}

@end
8 changes: 8 additions & 0 deletions ios/sdk/component/textinput/HippyTextView.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@
@property (nonatomic, strong) NSNumber *fontSize;
@property (nonatomic, strong) NSString *defaultValue;
@property (nonatomic, strong) UIColor *textColor;

/// ParagraphStyles - lineHeight
@property (nonatomic, strong) NSNumber *lineHeight;
/// ParagraphStyles - lineSpacing
@property (nonatomic, strong) NSNumber *lineSpacing;
/// ParagraphStyles - lineHeightMultiple
@property (nonatomic, strong) NSNumber *lineHeightMultiple;

@property (nonatomic, copy) HippyDirectEventBlock onChangeText;
@property (nonatomic, copy) HippyDirectEventBlock onBlur;
@property (nonatomic, copy) HippyDirectEventBlock onFocus;
Expand Down
99 changes: 96 additions & 3 deletions ios/sdk/component/textinput/HippyTextView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ - (void)didMoveToWindow {
@end

@interface HippyTextView () <HippyUITextViewResponseDelegate>

/// ParagraphStyle for TextView and PlaceholderView,
/// used for lineHeight config and etc.
@property (nonatomic, strong) NSMutableParagraphStyle *paragraphStyle;

@end

@implementation HippyTextView {
Expand All @@ -98,6 +103,10 @@ @implementation HippyTextView {
BOOL _viewDidCompleteInitialLayout;
}

@dynamic lineHeight;
@dynamic lineSpacing;
@dynamic lineHeightMultiple;

#pragma mark - Keyboard Events

- (void)keyboardWillShow:(NSNotification *)aNotification {
Expand Down Expand Up @@ -320,11 +329,19 @@ - (void)updatePlaceholder {
_placeholderView.scrollEnabled = NO;
_placeholderView.editable = NO;
_placeholderView.scrollsToTop = NO;
_placeholderView.attributedText = [[NSAttributedString alloc] initWithString:_placeholder attributes:@{
NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:_placeholder
attributes:@{
NSFontAttributeName: (_textView.font ? _textView.font : [self defaultPlaceholderFont]),
NSForegroundColorAttributeName: _placeholderTextColor
NSForegroundColorAttributeName: _placeholderTextColor
}];
if (self.paragraphStyle) {
// Apply paragraph style to the entire string
[attrStr addAttribute:NSParagraphStyleAttributeName
value:self.paragraphStyle
range:NSMakeRange(0, attrStr.length)];
}
_placeholderView.textAlignment = _textView.textAlignment;
_placeholderView.attributedText = attrStr;

[self insertSubview:_placeholderView belowSubview:_textView];
[self updatePlaceholderVisibility];
Expand All @@ -340,6 +357,40 @@ - (void)setFont:(UIFont *)font {
[self updatePlaceholder];
}

- (void)setLineHeight:(NSNumber *)lineHeight {
// create paragraphStyle, update placeholder and textView
if (!self.paragraphStyle) {
self.paragraphStyle = [[NSMutableParagraphStyle alloc] init];
}
self.paragraphStyle.minimumLineHeight = [lineHeight doubleValue];
self.paragraphStyle.maximumLineHeight = [lineHeight doubleValue];

[self updateParagraphAndFontStyleForTextView:_textView];
[self updatePlaceholder];
}

- (void)setLineSpacing:(NSNumber *)lineSpacing {
// create paragraphStyle, update placeholder and textView
if (!self.paragraphStyle) {
self.paragraphStyle = [[NSMutableParagraphStyle alloc] init];
}
self.paragraphStyle.lineSpacing = [lineSpacing doubleValue];

[self updateParagraphAndFontStyleForTextView:_textView];
[self updatePlaceholder];
}

- (void)setLineHeightMultiple:(NSNumber *)lineHeightMultiple {
// create paragraphStyle, update placeholder and textView
if (!self.paragraphStyle) {
self.paragraphStyle = [[NSMutableParagraphStyle alloc] init];
}
self.paragraphStyle.lineHeightMultiple = [lineHeightMultiple doubleValue];

[self updateParagraphAndFontStyleForTextView:_textView];
[self updatePlaceholder];
}

- (void)setPlaceholder:(NSString *)placeholder {
_placeholder = placeholder;
[self updatePlaceholder];
Expand Down Expand Up @@ -435,7 +486,8 @@ - (void)setText:(NSString *)text {
NSInteger oldTextLength = _textView.text.length;

_predictedText = text;
_textView.text = text;
// Use `attribuedText` instead of `text` to show paragraphStyle
_textView.attributedText = [self attributedTextAfterApplyingParagraphStyle:text];
[self textViewDidChange:_textView];
if (selection.empty) {
// maintain cursor position relative to the end of the old text
Expand Down Expand Up @@ -495,6 +547,8 @@ - (void)textViewDidBeginEditing:(__unused UITextView *)textView {
_textView.text = @"";
[self updatePlaceholderVisibility];
}
// update typingAttributes
[self updateTypingAttributes];
}

static BOOL findMismatch(NSString *first, NSString *second, NSRange *firstRange, NSRange *secondRange) {
Expand Down Expand Up @@ -777,4 +831,43 @@ - (void)setTextViewKeyboardAppearance {
}
}

#pragma mark - ParagraphStyle Related

- (void)updateTypingAttributes {
if (self.paragraphStyle) {
// Set typingAttributes if needed
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSParagraphStyleAttributeName] = self.paragraphStyle;
if (_textView.font) {
attrs[NSFontAttributeName] = _textView.font;
}
_textView.typingAttributes = attrs;
}
}

- (NSAttributedString *)attributedTextAfterApplyingParagraphStyle:(NSString *)text {
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];

if (self.paragraphStyle) {
// add paragraph style to the entire string
[attributedString addAttribute:NSParagraphStyleAttributeName
value:self.paragraphStyle
range:NSMakeRange(0, attributedString.length)];
}
if (_textView.font) {
// add font style to the entire string
[attributedString addAttribute:NSFontAttributeName
value:_textView.font
range:NSMakeRange(0, attributedString.length)];
}
return attributedString;
}

- (void)updateParagraphAndFontStyleForTextView:(UITextView *)textView {
if (textView.text.length == 0) {
return;
}
textView.attributedText = [self attributedTextAfterApplyingParagraphStyle:textView.text];
}

@end
6 changes: 6 additions & 0 deletions ios/sdk/component/textinput/HippyTextViewManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,13 @@ - (HippyShadowView *)shadowView {

HIPPY_EXPORT_SHADOW_PROPERTY(text, NSString)
HIPPY_EXPORT_SHADOW_PROPERTY(placeholder, NSString)
HIPPY_EXPORT_SHADOW_PROPERTY(lineHeight, NSNumber)
HIPPY_EXPORT_SHADOW_PROPERTY(lineSpacing, NSNumber)
HIPPY_EXPORT_SHADOW_PROPERTY(lineHeightMultiple, NSNumber)

HIPPY_EXPORT_VIEW_PROPERTY(lineHeight, NSNumber)
HIPPY_EXPORT_VIEW_PROPERTY(lineSpacing, NSNumber)
HIPPY_EXPORT_VIEW_PROPERTY(lineHeightMultiple, NSNumber)
HIPPY_REMAP_VIEW_PROPERTY(autoCapitalize, textView.autocapitalizationType, UITextAutocapitalizationType)
HIPPY_EXPORT_VIEW_PROPERTY(autoCorrect, BOOL)
HIPPY_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL)
Expand Down

0 comments on commit 33184a2

Please sign in to comment.