|
4 | 4 |
|
5 | 5 | #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h" |
6 | 6 |
|
| 7 | +#import <CoreText/CoreText.h> |
7 | 8 | #import <Foundation/Foundation.h> |
8 | 9 | #import <UIKit/UIKit.h> |
9 | 10 |
|
|
74 | 75 |
|
75 | 76 | #pragma mark - Static Functions |
76 | 77 |
|
| 78 | +// static CFMutableCharacterSetRef EmojiCharacterSet() { |
| 79 | +// static CFMutableCharacterSetRef set = nil; |
| 80 | +// static dispatch_once_t onceToken; |
| 81 | +// dispatch_once(&onceToken, ^{ |
| 82 | +// set = CFCharacterSetCreateMutableCopy( |
| 83 | +// kCFAllocatorDefault, |
| 84 | +// CTFontCopyCharacterSet(CTFontCreateWithName(CFSTR("AppleColorEmoji"), 0.0, NULL))); |
| 85 | +// CFCharacterSetRemoveCharactersInString(set, CFSTR(" 0123456789#*")); |
| 86 | +// }); |
| 87 | +// return set; |
| 88 | +// } |
| 89 | + |
| 90 | +// static NSString* GetEmoji(NSString* string) { |
| 91 | +// CFRange result; |
| 92 | +// BOOL found = CFStringFindCharacterFromSet((CFStringRef)string, EmojiCharacterSet(), |
| 93 | +// CFRangeMake(0, string.length), 0, &result); |
| 94 | +// if (!found) { |
| 95 | +// return nil; |
| 96 | +// } |
| 97 | +// return [string substringWithRange:NSMakeRange(result.location, result.length)]; |
| 98 | +// } |
| 99 | + |
77 | 100 | // "TextInputType.none" is a made-up input type that's typically |
78 | 101 | // used when there's an in-app virtual keyboard. If |
79 | 102 | // "TextInputType.none" is specified, disable the system |
@@ -702,6 +725,7 @@ @interface FlutterTextInputView () |
702 | 725 | @property(nonatomic, assign) CGRect markedRect; |
703 | 726 | @property(nonatomic) BOOL isVisibleToAutofill; |
704 | 727 | @property(nonatomic, assign) BOOL accessibilityEnabled; |
| 728 | +@property(nonatomic, copy) NSString* lastComposedCharacters; |
705 | 729 |
|
706 | 730 | - (void)setEditableTransform:(NSArray*)matrix; |
707 | 731 | @end |
@@ -880,6 +904,8 @@ - (void)dealloc { |
880 | 904 | [_markedTextStyle release]; |
881 | 905 | [_textContentType release]; |
882 | 906 | [_textInteraction release]; |
| 907 | + [_lastComposedCharacters release]; |
| 908 | + _lastComposedCharacters = nil; |
883 | 909 | [super dealloc]; |
884 | 910 | } |
885 | 911 |
|
@@ -1848,6 +1874,10 @@ - (BOOL)hasText { |
1848 | 1874 | } |
1849 | 1875 |
|
1850 | 1876 | - (void)insertText:(NSString*)text { |
| 1877 | + if (!text.UTF8String && text.length > 0 && text.length == 1 && |
| 1878 | + [text characterAtIndex:0] == [self.lastComposedCharacters characterAtIndex:0]) { |
| 1879 | + text = self.lastComposedCharacters; |
| 1880 | + } |
1851 | 1881 | NSMutableArray<FlutterTextSelectionRect*>* copiedRects = |
1852 | 1882 | [[NSMutableArray alloc] initWithCapacity:[_selectionRects count]]; |
1853 | 1883 | NSAssert([_selectedTextRange.start isKindOfClass:[FlutterTextPosition class]], |
@@ -1936,6 +1966,12 @@ - (void)deleteBackward { |
1936 | 1966 | } |
1937 | 1967 |
|
1938 | 1968 | if (!_selectedTextRange.isEmpty) { |
| 1969 | + NSString* deletedText = [self.text substringWithRange:_selectedTextRange.range]; |
| 1970 | + CFRange range = |
| 1971 | + CFStringGetRangeOfComposedCharactersAtIndex((__bridge CFStringRef)deletedText, 0); |
| 1972 | + self.lastComposedCharacters = |
| 1973 | + [deletedText substringWithRange:NSMakeRange(range.location, range.length)]; |
| 1974 | + |
1939 | 1975 | [self replaceRange:_selectedTextRange withText:@""]; |
1940 | 1976 | } |
1941 | 1977 | } |
|
0 commit comments