From a39660f58bb2ec6be09439c347cde3da659efc8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20=C5=BB=C3=B3=C5=82kiewski?= Date: Fri, 21 Nov 2025 12:45:32 +0100 Subject: [PATCH] feat: add rtl support on iOS --- ios/EnrichedTextInputView.h | 1 + ios/EnrichedTextInputView.mm | 18 ++++++++++++- ios/utils/LayoutManagerExtension.mm | 40 ++++++++++++++++++++++++----- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/ios/EnrichedTextInputView.h b/ios/EnrichedTextInputView.h index 962cd2f9..1eaa8064 100644 --- a/ios/EnrichedTextInputView.h +++ b/ios/EnrichedTextInputView.h @@ -5,6 +5,7 @@ #import "InputParser.h" #import "BaseStyleProtocol.h" #import "InputTextView.h" +#import "RCTI18nUtil.h" #ifndef EnrichedTextInputViewNativeComponent_h #define EnrichedTextInputViewNativeComponent_h diff --git a/ios/EnrichedTextInputView.mm b/ios/EnrichedTextInputView.mm index d588ab0f..ea8ebc2e 100644 --- a/ios/EnrichedTextInputView.mm +++ b/ios/EnrichedTextInputView.mm @@ -415,7 +415,7 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & defaultTypingAttributes[NSFontAttributeName] = [config primaryFont]; defaultTypingAttributes[NSUnderlineColorAttributeName] = [config primaryColor]; defaultTypingAttributes[NSStrikethroughColorAttributeName] = [config primaryColor]; - defaultTypingAttributes[NSParagraphStyleAttributeName] = [[NSParagraphStyle alloc] init]; + defaultTypingAttributes[NSParagraphStyleAttributeName] = [self prepareDefaultParagraphStyle]; textView.typingAttributes = defaultTypingAttributes; // update the placeholder as well @@ -522,6 +522,22 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & } } +- (NSMutableParagraphStyle * )prepareDefaultParagraphStyle +{ + NSMutableParagraphStyle *pStyle = [[NSMutableParagraphStyle alloc] init]; + + BOOL isRTL = [[RCTI18nUtil sharedInstance] isRTL]; + + if (isRTL) { + pStyle.baseWritingDirection = NSWritingDirectionRightToLeft; + } else { + pStyle.baseWritingDirection = NSWritingDirectionLeftToRight; + } + pStyle.baseWritingDirection = NSWritingDirectionRightToLeft; + + return pStyle; +} + - (void)setPlaceholderLabelShown:(BOOL)shown { if(shown) { [self refreshPlaceholderLabelStyles]; diff --git a/ios/utils/LayoutManagerExtension.mm b/ios/utils/LayoutManagerExtension.mm index 26a9cbcd..b3e42c18 100644 --- a/ios/utils/LayoutManagerExtension.mm +++ b/ios/utils/LayoutManagerExtension.mm @@ -65,12 +65,17 @@ - (void)my_drawBackgroundForGlyphRange:(NSRange)glyphRange atPoint:(CGPoint)orig NSRange paragraphGlyphRange = [self glyphRangeForCharacterRange:paragraphRange actualCharacterRange:nullptr]; [self enumerateLineFragmentsForGlyphRange:paragraphGlyphRange usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer * _Nonnull textContainer, NSRange glyphRange, BOOL * _Nonnull stop) { - CGFloat paddingLeft = origin.x; - CGFloat paddingTop = origin.y; - CGFloat x = paddingLeft; - CGFloat y = paddingTop + rect.origin.y; + BOOL isRTL = [[RCTI18nUtil sharedInstance] isRTL]; CGFloat width = [typedInput->config blockquoteBorderWidth]; CGFloat height = rect.size.height; + + CGFloat x = 0; + if (isRTL) { + x = origin.x + rect.size.width - width; + } else { + x = origin.x; + } + CGFloat y = origin.y + rect.origin.y; CGRect lineRect = CGRectMake(x, y, width, height); [[typedInput->config blockquoteBorderColor] setFill]; @@ -103,18 +108,34 @@ - (void)my_drawBackgroundForGlyphRange:(NSRange)glyphRange atPoint:(CGPoint)orig [self enumerateLineFragmentsForGlyphRange:paragraphGlyphRange usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer *container, NSRange lineGlyphRange, BOOL *stop) { NSString *marker = [self markerForList:pStyle.textLists.firstObject charIndex:[self characterIndexForGlyphAtIndex:lineGlyphRange.location] input:typedInput]; + BOOL isRTL = [[RCTI18nUtil sharedInstance] isRTL]; + + CGFloat textStartLeft = usedRect.origin.x; + CGFloat textEndRight = usedRect.origin.x + usedRect.size.width; if(pStyle.textLists.firstObject.markerFormat == NSTextListMarkerDecimal) { CGFloat gapWidth = [typedInput->config orderedListGapWidth]; CGFloat markerWidth = [marker sizeWithAttributes:markerAttributes].width; - CGFloat markerX = usedRect.origin.x - gapWidth - markerWidth/2; + CGFloat markerX = 0; + + if (isRTL) { + markerX = textEndRight + gapWidth; + } else { + markerX = textStartLeft - gapWidth - markerWidth / 2; + } [marker drawAtPoint:CGPointMake(markerX, usedRect.origin.y + origin.y) withAttributes:markerAttributes]; } else { CGFloat gapWidth = [typedInput->config unorderedListGapWidth]; CGFloat bulletSize = [typedInput->config unorderedListBulletSize]; - CGFloat bulletX = usedRect.origin.x - gapWidth - bulletSize/2; CGFloat centerY = CGRectGetMidY(usedRect); + CGFloat bulletX = 0; + + if (isRTL) { + bulletX = textEndRight + gapWidth + (bulletSize / 2.0); + } else { + bulletX = textStartLeft - gapWidth - (bulletSize / 2.0); + } CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); { @@ -161,8 +182,13 @@ - (NSString *)markerForList:(NSTextList *)list charIndex:(NSUInteger)index input itemNumber = prevParagraphsCount + 1; } + BOOL isRTL = [[RCTI18nUtil sharedInstance] isRTL]; - return [NSString stringWithFormat:@"%ld.", (long)(itemNumber)]; + if (isRTL) { + return [NSString stringWithFormat:@".%ld", (long)(itemNumber)]; + } else { + return [NSString stringWithFormat:@"%ld.", (long)(itemNumber)]; + } } else { return @"•"; }