This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Doric/doric-iOS/Pod/Classes/Shader/DoricInputNode.m

721 lines
27 KiB
Mathematica
Raw Permalink Normal View History

2019-12-11 14:14:20 +08:00
/*
* Copyright [2019] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//
// DoricInputNode.m
// Doric
//
// Created by on 2019/12/11.
//
2021-06-11 17:47:06 +08:00
#import <JavaScriptCore/JavaScriptCore.h>
2019-12-11 14:14:20 +08:00
#import "DoricInputNode.h"
#import "DoricUtil.h"
#import "DoricPromise.h"
2020-06-13 11:53:21 +08:00
typedef void (^onTextChangeBlock)(NSString *text, DoricInputNode *node);
typedef void (^onFocusChangeBlock)(BOOL focused, DoricInputNode *node);
2019-12-11 14:14:20 +08:00
2021-06-11 15:17:20 +08:00
typedef void (^onSubmitEditingBlock)(NSString *text, DoricInputNode *node);
@interface DoricSingleLineInput : UITextField
@end
@implementation DoricSingleLineInput
- (void)drawTextInRect:(CGRect)rect {
[super drawTextInRect:rect];
}
- (CGSize)sizeThatFits:(CGSize)size {
return [super sizeThatFits:size];
}
@end
2020-05-06 15:11:57 +08:00
2021-09-08 20:20:06 +08:00
@interface DoricMultilineInput : UITextView
@property(nonatomic, assign) DoricGravity gravity;
2021-09-08 20:20:06 +08:00
@property(nonatomic, strong) UILabel *placeholderLabel;
@end
@implementation DoricMultilineInput
2020-05-06 15:11:57 +08:00
- (instancetype)init {
if (self = [super init]) {
self.font = [UIFont systemFontOfSize:12];
_placeholderLabel = [UILabel new];
_placeholderLabel.numberOfLines = 0;
_placeholderLabel.textColor = [UIColor grayColor];
_placeholderLabel.userInteractionEnabled = NO;
_placeholderLabel.font = self.font;
[self insertSubview:_placeholderLabel atIndex:0];
}
return self;
}
- (void)setText:(NSString *)text {
[super setText:text];
self.placeholderLabel.hidden = self.text.length > 0;
}
2020-05-06 15:11:57 +08:00
- (void)layoutSubviews {
[super layoutSubviews];
2021-09-09 13:55:58 +08:00
if (self.contentSize.height < self.height) {
if ((self.gravity & DoricGravityTop) == DoricGravityTop) {
self.contentInset = UIEdgeInsetsMake(
0,
self.contentInset.left,
self.contentInset.bottom,
self.contentInset.right);
} else if ((self.gravity & DoricGravityBottom) == DoricGravityBottom) {
self.contentInset = UIEdgeInsetsMake(
self.height - self.contentSize.height,
self.contentInset.left,
self.contentInset.bottom,
self.contentInset.right);
} else {
self.contentInset = UIEdgeInsetsMake(
(self.height - self.contentSize.height) / 2,
self.contentInset.left,
self.contentInset.bottom,
self.contentInset.right);
}
}
self.placeholderLabel.hidden = self.text.length > 0;
if (!self.placeholderLabel.hidden) {
CGFloat lineFragmentPadding = self.textContainer.lineFragmentPadding;
UIEdgeInsets textContainerInset = self.textContainerInset;
self.placeholderLabel.x = lineFragmentPadding + textContainerInset.left;
CGFloat desiredWidth = self.width - lineFragmentPadding * 2 - textContainerInset.left - textContainerInset.right;
CGSize fitSize = [self.placeholderLabel sizeThatFits:CGSizeMake(desiredWidth, 0)];
if (fitSize.width < desiredWidth) {
self.placeholderLabel.width = desiredWidth;
}
self.placeholderLabel.height = fitSize.height;
if ((self.gravity & DoricGravityTop) == DoricGravityTop) {
self.placeholderLabel.y = textContainerInset.top;
} else if ((self.gravity & DoricGravityBottom) == DoricGravityBottom) {
self.placeholderLabel.y = self.height - textContainerInset.bottom - fitSize.height ;
} else {
self.placeholderLabel.centerY = (self.height - textContainerInset.top - textContainerInset.bottom) / 2 ;
}
if (self.contentInset.top > 0) {
self.placeholderLabel.y = self.placeholderLabel.y - self.contentInset.top;
}
}
2020-05-06 15:11:57 +08:00
}
- (CGSize)sizeThatFits:(CGSize)size {
if (self.text.length > 0) {
CGSize ret = [super sizeThatFits:size];
return CGSizeMake(ret.width - self.doricLayout.paddingLeft - self.doricLayout.paddingRight, ret.height - self.doricLayout.paddingTop - self.doricLayout.paddingBottom);
} else {
CGSize ret = [self.placeholderLabel sizeThatFits:size];
return CGSizeMake(ret.width, ret.height);
}
}
2021-09-08 20:20:06 +08:00
- (void)setTextAlignment:(NSTextAlignment)textAlignment {
[super setTextAlignment:textAlignment];
self.placeholderLabel.textAlignment = textAlignment;
}
@end
@interface DoricInputView ()
@property(nonatomic, strong) DoricMultilineInput *multiLineInput;
@property(nonatomic, strong) DoricSingleLineInput *singleLineInput;
2021-09-09 15:10:42 +08:00
@property(nonatomic, strong) UIFont *hintFont;
2021-09-08 20:20:06 +08:00
@end
@implementation DoricInputView
- (instancetype)init {
if (self = [super init]) {
_multiLineInput = [DoricMultilineInput new];
_multiLineInput.backgroundColor = UIColor.clearColor;
2021-09-09 13:55:58 +08:00
_multiLineInput.textAlignment = NSTextAlignmentLeft;
_multiLineInput.gravity = DoricGravityTop;
2021-09-08 20:20:06 +08:00
[self addSubview:_multiLineInput];
_singleLineInput = [DoricSingleLineInput new];
2021-09-08 20:20:06 +08:00
_singleLineInput.backgroundColor = UIColor.clearColor;
2021-09-09 13:55:58 +08:00
_singleLineInput.textAlignment = NSTextAlignmentLeft;
_singleLineInput.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
2021-09-08 20:20:06 +08:00
[self addSubview:_singleLineInput];
self.multiline = YES;
}
return self;
}
- (void)setMultiline:(BOOL)multiline {
if (multiline == self.multiline) {
return;
}
2021-09-09 14:13:22 +08:00
if (multiline) {
self.multiLineInput.text = self.singleLineInput.text;
if (self.singleLineInput.isFirstResponder) {
[self.multiLineInput becomeFirstResponder];
}
} else {
self.singleLineInput.text = self.multiLineInput.text;
if (self.multiLineInput.isFirstResponder) {
[self.singleLineInput becomeFirstResponder];
}
}
2021-09-08 20:20:06 +08:00
self.singleLineInput.hidden = multiline;
self.multiLineInput.hidden = !multiline;
}
- (BOOL)multiline {
return self.singleLineInput.hidden;
}
- (void)setFrame:(CGRect)frame {
[super setFrame:frame];
2021-09-09 13:55:58 +08:00
self.singleLineInput.width = frame.size.width - self.doricLayout.paddingLeft - self.doricLayout.paddingRight;
self.singleLineInput.height = frame.size.height - self.doricLayout.paddingTop - self.doricLayout.paddingBottom;
self.singleLineInput.x = self.doricLayout.paddingLeft;
self.singleLineInput.y = self.doricLayout.paddingTop;
self.multiLineInput.width = frame.size.width - self.doricLayout.paddingLeft - self.doricLayout.paddingRight;
self.multiLineInput.height = frame.size.height - self.doricLayout.paddingTop - self.doricLayout.paddingBottom;
self.multiLineInput.x = self.doricLayout.paddingLeft;
self.multiLineInput.y = self.doricLayout.paddingTop;
2021-09-08 20:20:06 +08:00
}
- (CGSize)sizeThatFits:(CGSize)size {
if (self.multiline) {
return [self.multiLineInput sizeThatFits:size];
} else {
return [self.singleLineInput sizeThatFits:size];
}
}
- (void)setText:(NSString *)text {
self.multiLineInput.text = text;
self.singleLineInput.text = text;
}
- (NSString *)text {
if (self.multiline) {
return self.multiLineInput.text;
} else {
return self.singleLineInput.text;
}
}
- (void)setFont:(UIFont *)font {
self.multiLineInput.font = font;
self.singleLineInput.font = font;
}
- (UIFont *)font {
if (self.multiline) {
return self.multiLineInput.font;
} else {
return self.singleLineInput.font;
}
}
- (void)setTextColor:(UIColor *)color {
self.multiLineInput.textColor = color;
self.singleLineInput.textColor = color;
}
- (UIColor *)textColor {
if (self.multiline) {
return self.multiLineInput.textColor;
} else {
return self.singleLineInput.textColor;
}
}
- (void)setTextAlignment:(NSTextAlignment)textAlignment {
self.multiLineInput.textAlignment = textAlignment;
self.singleLineInput.textAlignment = textAlignment;
}
- (NSTextAlignment)textAlignment {
if (self.multiline) {
return self.multiLineInput.textAlignment;
} else {
return self.singleLineInput.textAlignment;
}
}
- (void)setHintText:(NSString *)text {
self.multiLineInput.placeholderLabel.text = text;
}
- (NSString *)hintText {
if (self.multiline) {
return self.multiLineInput.placeholderLabel.text;
} else {
return self.singleLineInput.placeholder;
}
}
- (void)setHintTextColor:(UIColor *)color {
self.multiLineInput.placeholderLabel.textColor = color;
}
- (void)setHintFont:(UIFont *)font {
2021-09-09 15:10:42 +08:00
_hintFont = font;
2021-09-08 20:20:06 +08:00
self.multiLineInput.placeholderLabel.font = font;
}
- (void)setKeyboardType:(UIKeyboardType)keyboardType {
self.multiLineInput.keyboardType = keyboardType;
self.singleLineInput.keyboardType = keyboardType;
}
- (void)setReturnKeyType:(UIReturnKeyType)returnKeyType {
self.multiLineInput.returnKeyType = returnKeyType;
self.singleLineInput.returnKeyType = returnKeyType;
}
- (void)setSecureTextEntry:(BOOL)secureTextEntry {
self.multiLineInput.secureTextEntry = secureTextEntry;
self.singleLineInput.secureTextEntry = secureTextEntry;
}
- (void)setEditable:(BOOL)editable {
self.multiLineInput.editable = editable;
self.singleLineInput.enabled = editable;
}
2020-05-06 15:11:57 +08:00
@end
2021-09-08 20:20:06 +08:00
@interface DoricInputNode () <UITextViewDelegate, UITextFieldDelegate>
2019-12-11 14:14:20 +08:00
@property(nonatomic, copy) onTextChangeBlock onTextChange;
2021-06-11 15:17:20 +08:00
@property(nonatomic, copy) onFocusChangeBlock onFocusChange;
@property(nonatomic, copy) onSubmitEditingBlock onSubmitEditing;
2020-04-30 18:31:26 +08:00
@property(nonatomic, strong) NSNumber *maxLength;
2021-06-11 17:47:06 +08:00
@property(nonatomic, copy) NSString *beforeTextChangeFuncId;
2023-01-17 11:18:15 +08:00
@property(nonatomic, assign) BOOL customizedFont;
2019-12-11 14:14:20 +08:00
@end
@implementation DoricInputNode
2020-05-06 15:11:57 +08:00
- (DoricInputView *)build {
2021-09-08 20:20:06 +08:00
DoricInputView *v = [DoricInputView new];
v.singleLineInput.delegate = self;
2021-09-09 14:13:22 +08:00
[v.singleLineInput addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
2021-09-08 20:20:06 +08:00
v.multiLineInput.delegate = self;
v.multiLineInput.textContainer.lineFragmentPadding = 0;
v.doricLayout.paddingTop = v.multiLineInput.textContainerInset.top;
v.doricLayout.paddingBottom = v.multiLineInput.textContainerInset.bottom;
v.doricLayout.paddingLeft = v.multiLineInput.textContainerInset.left;
v.doricLayout.paddingRight = v.multiLineInput.textContainerInset.right;
2021-09-09 13:55:58 +08:00
v.multiLineInput.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
2019-12-11 14:14:20 +08:00
return v;
}
2020-05-06 15:11:57 +08:00
- (void)blendView:(DoricInputView *)view forPropName:(NSString *)name propValue:(id)prop {
2019-12-11 14:14:20 +08:00
if ([name isEqualToString:@"text"]) {
view.text = prop;
} else if ([name isEqualToString:@"textSize"]) {
2021-07-20 15:46:49 +08:00
UIFont *font = view.font;
if (font) {
view.font = [view.font fontWithSize:[(NSNumber *) prop floatValue]];
} else {
view.font = [UIFont systemFontOfSize:[(NSNumber *) prop floatValue]];
}
2019-12-11 14:14:20 +08:00
} else if ([name isEqualToString:@"textColor"]) {
view.textColor = DoricColor(prop);
} else if ([name isEqualToString:@"textAlignment"]) {
DoricGravity gravity = (DoricGravity) [(NSNumber *) prop integerValue];
NSTextAlignment alignment = NSTextAlignmentCenter;
2020-03-27 10:07:53 +08:00
if ((gravity & DoricGravityLeft) == DoricGravityLeft) {
2019-12-11 14:14:20 +08:00
alignment = NSTextAlignmentLeft;
2020-03-27 10:07:53 +08:00
} else if ((gravity & DoricGravityRight) == DoricGravityRight) {
2019-12-11 14:14:20 +08:00
alignment = NSTextAlignmentRight;
}
view.textAlignment = alignment;
view.multiLineInput.gravity = gravity;
UIControlContentVerticalAlignment verticalAlignment = UIControlContentVerticalAlignmentCenter;
if ((gravity & DoricGravityTop) == DoricGravityTop) {
verticalAlignment = UIControlContentVerticalAlignmentTop;
} else if ((gravity & DoricGravityBottom) == DoricGravityBottom) {
verticalAlignment = UIControlContentVerticalAlignmentBottom;
}
view.singleLineInput.contentVerticalAlignment = verticalAlignment;
2023-01-17 11:18:15 +08:00
} else if ([name isEqualToString:@"fontStyle"]) {
UIFont *font = view.font;
if (!font) {
font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
}
UIFontDescriptor *fontDescriptor = nil;
if ([@"bold" isEqualToString:prop]) {
fontDescriptor = [font.fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
} else if ([@"italic" isEqualToString:prop]) {
fontDescriptor = [font.fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic];
} else if ([@"bold_italic" isEqualToString:prop]) {
fontDescriptor = [font.fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold | UIFontDescriptorTraitItalic];
}
if (fontDescriptor) {
font = [UIFont fontWithDescriptor:fontDescriptor size:0];
} else {
if (self.customizedFont) {
font = [UIFont fontWithName:font.fontName size:font.pointSize];
} else {
UIFont *systemFont = [UIFont systemFontOfSize:[UIFont systemFontSize]];
font = [UIFont fontWithName:systemFont.fontName size:font.pointSize];
}
}
view.font = font;
2021-07-20 15:46:49 +08:00
} else if ([name isEqualToString:@"font"]) {
NSString *iconfont = prop;
UIFont *font = [UIFont fontWithName:[iconfont stringByReplacingOccurrencesOfString:@".ttf" withString:@""]
size:view.font.pointSize];
view.font = font;
2023-01-17 11:18:15 +08:00
self.customizedFont = YES;
2019-12-11 14:14:20 +08:00
} else if ([name isEqualToString:@"multiline"]) {
2021-02-08 18:18:37 +08:00
BOOL value = [(NSNumber *) prop boolValue];
2021-09-08 20:20:06 +08:00
view.multiline = value;
2021-06-11 17:47:06 +08:00
} else if ([name isEqualToString:@"beforeTextChange"]) {
self.beforeTextChangeFuncId = prop;
2019-12-11 14:14:20 +08:00
} else if ([name isEqualToString:@"hintText"]) {
2021-09-08 20:20:06 +08:00
view.hintText = (NSString *) prop;
2019-12-11 14:14:20 +08:00
} else if ([name isEqualToString:@"hintTextColor"]) {
2021-09-08 20:20:06 +08:00
view.hintTextColor = DoricColor(prop);
2021-07-20 15:46:49 +08:00
} else if ([name isEqualToString:@"hintFont"]) {
NSString *iconfont = prop;
UIFont *font = [UIFont fontWithName:[iconfont stringByReplacingOccurrencesOfString:@".ttf" withString:@""]
size:view.font.pointSize];
2021-09-08 20:20:06 +08:00
view.hintFont = font;
2019-12-11 14:14:20 +08:00
} else if ([name isEqualToString:@"onTextChange"]) {
if ([prop isKindOfClass:[NSString class]]) {
self.onTextChange = ^(NSString *text, DoricInputNode *node) {
2020-06-13 11:53:21 +08:00
[node callJSResponse:prop, text, nil];
2019-12-11 14:14:20 +08:00
};
2020-06-13 11:53:21 +08:00
} else {
2019-12-11 14:14:20 +08:00
self.onTextChange = nil;
}
} else if ([name isEqualToString:@"onFocusChange"]) {
if ([prop isKindOfClass:[NSString class]]) {
2021-06-11 15:17:20 +08:00
self.onFocusChange = ^(BOOL focused, DoricInputNode *node) {
2020-06-13 11:53:21 +08:00
[node callJSResponse:prop, @(focused), nil];
2019-12-11 14:14:20 +08:00
};
2020-06-13 11:53:21 +08:00
} else {
2021-06-11 15:17:20 +08:00
self.onFocusChange = nil;
2019-12-11 14:14:20 +08:00
}
2020-04-30 18:31:26 +08:00
} else if ([name isEqualToString:@"maxLength"]) {
self.maxLength = prop;
2020-06-13 11:53:21 +08:00
} else if ([name isEqualToString:@"inputType"]) {
2020-06-12 16:33:16 +08:00
switch ([prop integerValue]) {
case 1: {
2020-06-13 11:53:21 +08:00
[self.view setKeyboardType:UIKeyboardTypeNumberPad];
2020-06-12 16:33:16 +08:00
break;
}
case 2: {
2020-06-13 11:53:21 +08:00
[self.view setKeyboardType:UIKeyboardTypeDecimalPad];
2020-06-12 16:33:16 +08:00
break;
}
case 3: {
2020-06-13 11:53:21 +08:00
[self.view setKeyboardType:UIKeyboardTypeAlphabet];
2020-06-12 16:33:16 +08:00
break;
}
case 4: {
2020-06-13 11:53:21 +08:00
[self.view setKeyboardType:UIKeyboardTypePhonePad];
2020-06-12 16:33:16 +08:00
break;
}
default: {
2020-06-13 11:53:21 +08:00
[self.view setKeyboardType:UIKeyboardTypeDefault];
2020-06-12 16:33:16 +08:00
break;
}
}
2021-02-08 18:18:37 +08:00
} else if ([name isEqualToString:@"password"]) {
view.secureTextEntry = [(NSNumber *) prop boolValue];
} else if ([name isEqualToString:@"editable"]) {
view.editable = [(NSNumber *) prop boolValue];
} else if ([name isEqualToString:@"returnKeyType"]) {
switch ([(NSNumber *) prop integerValue]) {
case 1:
view.returnKeyType = UIReturnKeyDone;
break;
case 2:
view.returnKeyType = UIReturnKeySearch;
break;
case 3:
view.returnKeyType = UIReturnKeyNext;
break;
case 4:
view.returnKeyType = UIReturnKeyGo;
break;
case 5:
view.returnKeyType = UIReturnKeySend;
break;
case 0:
default:
view.returnKeyType = UIReturnKeyDefault;
break;
}
2021-06-11 15:17:20 +08:00
} else if ([name isEqualToString:@"onSubmitEditing"]) {
if ([prop isKindOfClass:[NSString class]]) {
self.onSubmitEditing = ^(NSString *text, DoricInputNode *node) {
[node callJSResponse:prop, text, nil];
};
} else {
self.onSubmitEditing = nil;
}
} else if ([name isEqualToString:@"enableHorizontalScrollBar"]) {
2021-09-08 20:20:06 +08:00
view.multiLineInput.showsHorizontalScrollIndicator = [prop boolValue];;
} else if ([name isEqualToString:@"enableVerticalScrollBar"]) {
2021-09-08 20:20:06 +08:00
view.multiLineInput.showsVerticalScrollIndicator = [prop boolValue];;
2020-06-13 11:53:21 +08:00
} else {
2019-12-11 14:14:20 +08:00
[super blendView:view forPropName:name propValue:prop];
}
}
- (void)blend:(NSDictionary *)props {
[super blend:props];
2020-04-30 18:43:57 +08:00
}
2020-06-13 11:53:21 +08:00
2020-05-06 15:11:57 +08:00
- (void)afterBlended:(NSDictionary *)props {
[super afterBlended:props];
2021-09-09 15:10:42 +08:00
UIFont *font = self.view.hintFont;
if (font) {
self.view.multiLineInput.placeholderLabel.font = [self.view.multiLineInput.placeholderLabel.font fontWithSize:self.view.font.pointSize];
} else {
self.view.multiLineInput.placeholderLabel.font = self.view.multiLineInput.font;
}
self.view.multiLineInput.placeholderLabel.numberOfLines = self.view.multiLineInput.textContainer.maximumNumberOfLines;
if (self.view.multiLineInput.placeholderLabel.text) {
self.view.singleLineInput.attributedPlaceholder = [[NSAttributedString alloc]
initWithString:self.view.multiLineInput.placeholderLabel.text
attributes:@{
NSForegroundColorAttributeName: self.view.multiLineInput.placeholderLabel.textColor,
NSFontAttributeName: self.view.multiLineInput.placeholderLabel.font}];
2021-07-20 15:46:49 +08:00
}
2020-05-06 15:11:57 +08:00
}
2020-04-30 18:43:57 +08:00
- (void)requestLayout {
[super requestLayout];
2020-05-06 15:11:57 +08:00
[self.view setNeedsLayout];
2019-12-11 14:14:20 +08:00
}
#pragma mark - Doric-JS api
2020-06-13 11:53:21 +08:00
2019-12-11 14:14:20 +08:00
- (NSString *)getText {
return self.view.text;
}
- (void)setSelection:(NSDictionary *)params withPromise:(DoricPromise *)promise {
2021-09-08 20:20:06 +08:00
NSNumber *start = params[@"start"];
NSNumber *end = params[@"end"];
if (self.view.multiline) {
self.view.multiLineInput.selectedRange = NSMakeRange(start.unsignedIntegerValue, end.unsignedIntegerValue - start.unsignedIntegerValue);
} else {
UITextPosition *startPos = [self.view.singleLineInput positionFromPosition:self.view.singleLineInput.beginningOfDocument
offset:start.unsignedIntegerValue];
UITextPosition *endPos = [self.view.singleLineInput positionFromPosition:self.view.singleLineInput.beginningOfDocument
offset:end.unsignedIntegerValue];
self.view.singleLineInput.selectedTextRange = [self.view.singleLineInput textRangeFromPosition:startPos
toPosition:endPos];
2019-12-11 14:14:20 +08:00
}
[promise resolve:nil];
}
2021-06-11 17:40:02 +08:00
- (NSDictionary *)getSelection {
2021-09-08 20:20:06 +08:00
if (self.view.multiline) {
return @{
@"start": @([self.view.multiLineInput offsetFromPosition:self.view.multiLineInput.beginningOfDocument
toPosition:self.view.multiLineInput.selectedTextRange.start]),
@"end": @([self.view.multiLineInput offsetFromPosition:self.view.multiLineInput.beginningOfDocument
toPosition:self.view.multiLineInput.selectedTextRange.end]),
};
} else {
UITextRange *range = self.view.singleLineInput.selectedTextRange;
return @{
@"start": @( [self.view.singleLineInput offsetFromPosition:self.view.singleLineInput.beginningOfDocument
toPosition:range.start]),
@"end": @( [self.view.singleLineInput offsetFromPosition:self.view.singleLineInput.beginningOfDocument
toPosition:range.end]),
};
}
2021-06-11 17:40:02 +08:00
}
2019-12-11 14:14:20 +08:00
- (void)requestFocus {
2021-09-09 14:13:22 +08:00
if (self.view.multiline) {
[self.view.multiLineInput becomeFirstResponder];
} else {
[self.view.singleLineInput becomeFirstResponder];
}
2019-12-11 14:14:20 +08:00
}
- (void)releaseFocus {
2021-09-09 14:13:22 +08:00
if (self.view.multiline) {
[self.view.multiLineInput resignFirstResponder];
} else {
[self.view.singleLineInput resignFirstResponder];
}
2019-12-11 14:14:20 +08:00
}
#pragma mark - UITextViewDelegate
2020-06-13 11:53:21 +08:00
2021-09-09 14:13:22 +08:00
- (void)textViewDidBeginEditing:(UITextView *)textView {
2021-06-11 15:17:20 +08:00
if (self.onFocusChange) {
self.onFocusChange(YES, self);
2019-12-11 14:14:20 +08:00
}
}
2020-06-13 11:53:21 +08:00
2021-09-09 14:13:22 +08:00
- (void)textViewDidEndEditing:(UITextView *)textView {
2021-06-11 15:17:20 +08:00
if (self.onFocusChange) {
self.onFocusChange(NO, self);
}
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
2021-06-11 17:47:06 +08:00
if (self.beforeTextChangeFuncId) {
DoricAsyncResult *asyncResult = [self
pureCallJSResponse:self.beforeTextChangeFuncId,
@{
@"editing": textView.text,
@"start": @(range.location),
@"length": @(range.length),
@"replacement": text,
},
nil];
NSNumber *ret = [asyncResult waitUntilResult:^(JSValue *model) {
return [model toNumber];
}];
return [ret boolValue];
}
2019-12-11 14:14:20 +08:00
return YES;
}
- (void)textViewDidChange:(UITextView *)textView {
UITextRange *textRange = textView.markedTextRange;
if (textRange || textView.text.length > 0) {
2021-09-08 20:20:06 +08:00
self.view.multiLineInput.placeholderLabel.hidden = YES;
} else {
2021-09-08 20:20:06 +08:00
self.view.multiLineInput.placeholderLabel.hidden = NO;
}
if (textRange) {
NSString *text = [textView textInRange:textRange];
if (text.length) return;
}
2020-04-30 18:31:26 +08:00
if (self.maxLength) {
UITextRange *range = textView.selectedTextRange;
2021-06-08 18:20:37 +08:00
textView.text = [self limitToHansMaxLength:self.maxLength.unsignedIntValue text:textView.text];
textView.selectedTextRange = range;
2020-04-30 18:31:26 +08:00
}
2019-12-11 14:14:20 +08:00
if (self.onTextChange) {
self.onTextChange(textView.text, self);
}
2020-05-06 15:11:57 +08:00
[textView setNeedsLayout];
2019-12-11 14:14:20 +08:00
}
2020-06-13 11:53:21 +08:00
- (NSString *)limitToHansMaxLength:(NSUInteger)maxLen text:(NSString *)text {
NSUInteger asciiMaxLen = 2 * maxLen;
__block NSUInteger asciiLen = 0;
__block NSUInteger subStringRangeLen = 0;
[text enumerateSubstringsInRange:NSMakeRange(0, text.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
2020-06-13 11:53:21 +08:00
if ([substring canBeConvertedToEncoding:NSASCIIStringEncoding]) {
asciiLen += 2;
} else {
asciiLen += [substring lengthOfBytesUsingEncoding:NSUTF16StringEncoding];
}
if (asciiLen <= asciiMaxLen) {
subStringRangeLen = substringRange.location + substringRange.length;
} else {
*stop = YES;
}
}];
return [text substringWithRange:NSMakeRange(0, subStringRangeLen)];
}
2021-09-08 20:20:06 +08:00
2021-09-09 14:13:22 +08:00
- (void)textFieldDidChange:(UITextField *)textField {
UITextRange *textRange = textField.markedTextRange;
if (textRange) {
NSString *text = [textField textInRange:textRange];
if (text.length) return;
}
2021-09-08 20:20:06 +08:00
if (self.maxLength) {
UITextRange *range = textField.selectedTextRange;
2021-09-08 20:20:06 +08:00
textField.text = [self limitToHansMaxLength:self.maxLength.unsignedIntValue text:textField.text];
textField.selectedTextRange = range;
2021-09-08 20:20:06 +08:00
}
if (self.onTextChange) {
self.onTextChange(textField.text, self);
}
[textField setNeedsLayout];
}
2021-09-09 14:13:22 +08:00
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (self.onFocusChange) {
self.onFocusChange(YES, self);
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (self.onFocusChange) {
self.onFocusChange(NO, self);
}
}
2021-09-08 20:20:06 +08:00
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (self.beforeTextChangeFuncId) {
DoricAsyncResult *asyncResult = [self
pureCallJSResponse:self.beforeTextChangeFuncId,
@{
@"editing": textField.text,
@"start": @(range.location),
@"length": @(range.length),
@"replacement": string,
},
nil];
NSNumber *ret = [asyncResult waitUntilResult:^(JSValue *model) {
return [model toNumber];
}];
return [ret boolValue];
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (self.onSubmitEditing) {
self.onSubmitEditing(textField.text, self);
return YES;
} else {
return NO;
}
}
- (void)reset {
[super reset];
self.view.multiline = NO;
self.view.text = nil;
self.view.font = nil;
self.view.secureTextEntry = NO;
self.view.textAlignment = NSTextAlignmentNatural;
self.view.hintText = nil;
self.view.hintTextColor = UIColor.grayColor;
self.view.hintFont = nil;
self.view.editable = YES;
self.onFocusChange = nil;
self.onSubmitEditing = nil;
self.onTextChange = nil;
self.maxLength = nil;
2023-01-17 11:18:15 +08:00
self.customizedFont = NO;
}
2019-12-11 14:14:20 +08:00
@end