Skip to content

Commit b4180ca

Browse files
committed
fix: make attributes not reappear in empty lines
1 parent 8d4de9c commit b4180ca

3 files changed

Lines changed: 68 additions & 1 deletion

File tree

ios/EnrichedTextInputView.mm

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#import "WordsUtils.h"
1515
#import "LayoutManagerExtension.h"
1616
#import "ZeroWidthSpaceUtils.h"
17+
#import "ParagraphAttributesUtils.h"
1718

1819
using namespace facebook::react;
1920

@@ -977,6 +978,22 @@ - (void)manageSelectionBasedChanges {
977978
[mentionStyleClass manageMentionTypingAttributes];
978979
[mentionStyleClass manageMentionEditing];
979980
}
981+
982+
// typing attributes for empty lines selection reset
983+
NSString *currentString = [[textView.textStorage.string copy] stringByReplacingOccurrencesOfString:@"\u200B" withString:@""];
984+
if(textView.selectedRange.length == 0 && [_recentlyEmittedString isEqualToString: currentString] ) {
985+
// no string change means only a selection changed with no character changes
986+
NSRange paragraphRange = [textView.textStorage.string paragraphRangeForRange:textView.selectedRange];
987+
if(
988+
paragraphRange.length == 0 ||
989+
(paragraphRange.length == 1 &&
990+
[[NSCharacterSet newlineCharacterSet] characterIsMember:[textView.textStorage.string characterAtIndex:paragraphRange.location]])
991+
) {
992+
// user changed selection to an empty line (or empty line with a newline)
993+
// typing attributes need to be reset
994+
textView.typingAttributes = defaultTypingAttributes;
995+
}
996+
}
980997
}
981998

982999
- (void)handleWordModificationBasedChanges:(NSString*)word inRange:(NSRange)range {
@@ -1135,7 +1152,8 @@ - (bool)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range r
11351152
[h1Style handleNewlinesInRange:range replacementText:text] ||
11361153
[h2Style handleNewlinesInRange:range replacementText:text] ||
11371154
[h3Style handleNewlinesInRange:range replacementText:text] ||
1138-
[ZeroWidthSpaceUtils handleBackspaceInRange:range replacementText:text input:self]
1155+
[ZeroWidthSpaceUtils handleBackspaceInRange:range replacementText:text input:self] ||
1156+
[ParagraphAttributesUtils handleBackspaceInRange:range replacementText:text input:self]
11391157
) {
11401158
[self anyTextMayHaveBeenModified];
11411159
return NO;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#import <UIKit/UIKit.h>
2+
#pragma once
3+
4+
@interface ParagraphAttributesUtils : NSObject
5+
+ (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text input:(id)input;
6+
@end
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#import "ParagraphAttributesUtils.h"
2+
#import "EnrichedTextInputView.h"
3+
#import "ParagraphsUtils.h"
4+
#import "TextInsertionUtils.h"
5+
6+
@implementation ParagraphAttributesUtils
7+
8+
// if the user backspaces the last character in a line, the iOS applies typing attributes from the previous line
9+
// in the case of some paragraph styles it works especially bad when a list point just appears
10+
// hence the solution - reset typing attributes
11+
+ (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text input:(id)input {
12+
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)input;
13+
if(typedInput == nullptr) {
14+
return NO;
15+
}
16+
17+
// we make sure it was a backspace (text with 0 length) and it deleted something (range longer than 0)
18+
if(text.length > 0 || range.length == 0) {
19+
return NO;
20+
}
21+
22+
// find a non-newline range of the paragraph
23+
NSRange paragraphRange = [typedInput->textView.textStorage.string paragraphRangeForRange:range];
24+
NSArray *paragraphs = [ParagraphsUtils getNonNewlineRangesIn:typedInput->textView range:paragraphRange];
25+
if(paragraphs.count == 0) {
26+
return NO;
27+
}
28+
29+
NSRange nonNewlineRange = [(NSValue *)paragraphs.firstObject rangeValue];
30+
31+
// if the backspace removes the whole content of a paragraph - do the thing
32+
if(NSEqualRanges(nonNewlineRange, range)) {
33+
// do the replacement manually
34+
[TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:typedInput withSelection:YES];
35+
// reset typing attribtues
36+
typedInput->textView.typingAttributes = typedInput->defaultTypingAttributes;
37+
return YES;
38+
}
39+
40+
return NO;
41+
}
42+
43+
@end

0 commit comments

Comments
 (0)