Skip to content

Commit

Permalink
Improve performance on iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
maksg committed May 27, 2024
1 parent 377ab57 commit 2bc06d9
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 245 deletions.
21 changes: 8 additions & 13 deletions ios/MarkdownTextInputDecoratorView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#import <RNLiveMarkdown/MarkdownLayoutManager.h>
#import <RNLiveMarkdown/MarkdownTextInputDecoratorView.h>
#import <RNLiveMarkdown/RCTBackedTextFieldDelegateAdapter+Markdown.h>
#import <RNLiveMarkdown/RCTUITextView+Markdown.h>

#ifdef RCT_NEW_ARCH_ENABLED
Expand All @@ -23,7 +22,6 @@ @implementation MarkdownTextInputDecoratorView {
__weak RCTBaseTextInputView *_textInput;
#endif /* RCT_NEW_ARCH_ENABLED */
__weak UIView<RCTBackedTextInputViewProtocol> *_backedTextInputView;
__weak RCTBackedTextFieldDelegateAdapter *_adapter;
__weak RCTUITextView *_textView;
}

Expand Down Expand Up @@ -64,18 +62,14 @@ - (void)didMoveToWindow {
[_markdownUtils setMarkdownStyle:_markdownStyle];

[_textInput setMarkdownUtils:_markdownUtils];
if ([_backedTextInputView isKindOfClass:[RCTUITextField class]]) {
RCTUITextField *textField = (RCTUITextField *)_backedTextInputView;
_adapter = [textField valueForKey:@"textInputDelegateAdapter"];
[_adapter setMarkdownUtils:_markdownUtils];
} else if ([_backedTextInputView isKindOfClass:[RCTUITextView class]]) {
if ([_backedTextInputView isKindOfClass:[RCTUITextView class]]) {
_textView = (RCTUITextView *)_backedTextInputView;
[_textView setMarkdownUtils:_markdownUtils];
NSLayoutManager *layoutManager = _textView.layoutManager; // switching to TextKit 1 compatibility mode
layoutManager.allowsNonContiguousLayout = NO; // workaround for onScroll issue
object_setClass(layoutManager, [MarkdownLayoutManager class]);
[layoutManager setValue:_markdownUtils forKey:@"markdownUtils"];
} else {
} else if (![_backedTextInputView isKindOfClass:[RCTUITextField class]]) {
react_native_assert(false && "Cannot enable Markdown for this type of TextInput.");
}
}
Expand All @@ -85,9 +79,6 @@ - (void)willMoveToWindow:(UIWindow *)newWindow
if (_textInput != nil) {
[_textInput setMarkdownUtils:nil];
}
if (_adapter != nil) {
[_adapter setMarkdownUtils:nil];
}
if (_textView != nil) {
[_textView setMarkdownUtils:nil];
if (_textView.layoutManager != nil && [object_getClass(_textView.layoutManager) isEqual:[MarkdownLayoutManager class]]) {
Expand All @@ -103,11 +94,15 @@ - (void)setMarkdownStyle:(RCTMarkdownStyle *)markdownStyle
[_markdownUtils setMarkdownStyle:markdownStyle];

// apply new styles
if (_textView != nil) {
[_textView performSelector:@selector(textDidChange)];
} else {
#ifdef RCT_NEW_ARCH_ENABLED
[_textInput _setAttributedString:_backedTextInputView.attributedText];
[_textInput _setAttributedString:_backedTextInputView.attributedText];
#else
[_textInput setAttributedText:_textInput.attributedText];
[_textInput setAttributedText:_textInput.attributedText];
#endif /* RCT_NEW_ARCH_ENABLED */
}
}

@end
14 changes: 0 additions & 14 deletions ios/RCTBackedTextFieldDelegateAdapter+Markdown.h

This file was deleted.

43 changes: 0 additions & 43 deletions ios/RCTBackedTextFieldDelegateAdapter+Markdown.mm

This file was deleted.

11 changes: 9 additions & 2 deletions ios/RCTBaseTextInputView+Markdown.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
// This guard prevent this file to be compiled in the new architecture.
#ifndef RCT_NEW_ARCH_ENABLED

#import <React/RCTBaseTextInputView.h>
#import <RNLiveMarkdown/RCTMarkdownUtils.h>

NS_ASSUME_NONNULL_BEGIN

@interface RCTBaseTextInputView (Private)
- (BOOL)textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldText;
@end

@interface RCTBaseTextInputView (Markdown)

@property(nonatomic, nullable, getter=getMarkdownUtils) RCTMarkdownUtils *markdownUtils;
Expand All @@ -11,8 +18,8 @@ NS_ASSUME_NONNULL_BEGIN

- (BOOL)markdown_textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldText;

- (void)markdown_updateLocalData;

@end

NS_ASSUME_NONNULL_END

#endif /* RCT_NEW_ARCH_ENABLED */
47 changes: 12 additions & 35 deletions ios/RCTBaseTextInputView+Markdown.mm
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// This guard prevent this file to be compiled in the new architecture.
#ifndef RCT_NEW_ARCH_ENABLED

#import <React/RCTUITextField.h>
#import <RNLiveMarkdown/RCTUITextView+Markdown.h>
#import <RNLiveMarkdown/RCTBaseTextInputView+Markdown.h>
#import <RNLiveMarkdown/RCTMarkdownUtils.h>
#import <objc/message.h>
Expand All @@ -14,9 +19,11 @@ - (RCTMarkdownUtils *)getMarkdownUtils {

- (void)markdown_setAttributedText:(NSAttributedString *)attributedText
{
RCTMarkdownUtils *markdownUtils = [self getMarkdownUtils];
if (markdownUtils != nil) {
attributedText = [markdownUtils parseMarkdown:attributedText withAttributes:self.backedTextInputView.defaultTextAttributes];
if (![self.backedTextInputView isKindOfClass:[RCTUITextView class]]) {
RCTMarkdownUtils *markdownUtils = [self getMarkdownUtils];
if (markdownUtils != nil) {
attributedText = [markdownUtils parseMarkdown:attributedText withAttributes:self.backedTextInputView.defaultTextAttributes];
}
}

// Call the original method
Expand All @@ -33,29 +40,6 @@ - (BOOL)markdown_textOf:(NSAttributedString *)newText equals:(NSAttributedString
return [self markdown_textOf:newText equals:oldText];
}

- (void)markdown_updateLocalData
{
RCTMarkdownUtils *markdownUtils = [self getMarkdownUtils];
if (markdownUtils != nil) {
id<RCTBackedTextInputViewProtocol> backedTextInputView = self.backedTextInputView;
NSAttributedString *oldAttributedText = backedTextInputView.attributedText;
NSAttributedString *newAttributedText = [markdownUtils parseMarkdown:oldAttributedText withAttributes:backedTextInputView.defaultTextAttributes];
UITextRange *range = backedTextInputView.selectedTextRange;

// update attributed text without emitting onSelectionChange event
id<RCTBackedTextInputDelegate> delegate = backedTextInputView.textInputDelegate;
backedTextInputView.textInputDelegate = nil;
[backedTextInputView setAttributedText:newAttributedText];
backedTextInputView.textInputDelegate = delegate;

// restore original selection and emit onSelectionChange event
[backedTextInputView setSelectedTextRange:range notifyDelegate:YES];
}

// Call the original method
[self markdown_updateLocalData];
}

+ (void)load
{
static dispatch_once_t onceToken;
Expand All @@ -71,15 +55,6 @@ + (void)load
method_exchangeImplementations(originalMethod, swizzledMethod);
}

{
// swizzle updateLocalData
SEL originalSelector = @selector(updateLocalData);
SEL swizzledSelector = @selector(markdown_updateLocalData);
Method originalMethod = class_getInstanceMethod(cls, originalSelector);
Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
method_exchangeImplementations(originalMethod, swizzledMethod);
}

{
// swizzle textOf
SEL originalSelector = @selector(textOf:equals:);
Expand All @@ -92,3 +67,5 @@ + (void)load
}

@end

#endif /* RCT_NEW_ARCH_ENABLED */
1 change: 1 addition & 0 deletions ios/RCTMarkdownUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) NSMutableArray<NSDictionary *> *blockquoteRangesAndLevels;

- (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input withAttributes:(nullable NSDictionary<NSAttributedStringKey, id>*)attributes;
- (void)parseMarkdown:(nullable NSMutableAttributedString *)attributedString;

@end

Expand Down
Loading

0 comments on commit 2bc06d9

Please sign in to comment.