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

212 lines
7.5 KiB
Mathematica
Raw 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.
//
#import "DoricInputNode.h"
#import "DoricUtil.h"
#import "DoricPromise.h"
typedef void (^onTextChangeBlock)(NSString *text,DoricInputNode *node);
typedef void (^onFocusChangeBlock)(BOOL focused,DoricInputNode *node);
2020-05-06 15:11:57 +08:00
@implementation DoricInputView
- (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)layoutSubviews {
[super layoutSubviews];
self.placeholderLabel.hidden = self.text.length > 0;
if (self.placeholderLabel.hidden) {
return;
}
CGFloat lineFragmentPadding = self.textContainer.lineFragmentPadding;
UIEdgeInsets textContainerInset = self.textContainerInset;
self.placeholderLabel.x = lineFragmentPadding + textContainerInset.left;
self.placeholderLabel.y = textContainerInset.top;
self.placeholderLabel.width = self.width - lineFragmentPadding * 2 - textContainerInset.left - textContainerInset.right;
[self.placeholderLabel sizeToFit];
}
- (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);
}
}
@end
2019-12-11 14:14:20 +08:00
@interface DoricInputNode()<UITextViewDelegate>
@property(nonatomic, copy) onTextChangeBlock onTextChange;
@property(nonatomic, copy) onFocusChangeBlock onFocusShange;
2020-04-30 18:31:26 +08:00
@property(nonatomic, strong) NSNumber *maxLength;
2019-12-11 14:14:20 +08:00
@end
@implementation DoricInputNode
2020-05-06 15:11:57 +08:00
- (DoricInputView *)build {
DoricInputView *v = [[DoricInputView alloc] init];
2019-12-11 14:14:20 +08:00
v.delegate = self;
2020-05-06 15:11:57 +08:00
v.textContainer.lineFragmentPadding = 0;
v.doricLayout.paddingTop = v.textContainerInset.top;
v.doricLayout.paddingBottom = v.textContainerInset.bottom;
v.doricLayout.paddingLeft = v.textContainerInset.left;
v.doricLayout.paddingRight = v.textContainerInset.right;
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"]) {
view.font = [UIFont systemFontOfSize:[(NSNumber *) prop floatValue]];
} 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;
} else if ([name isEqualToString:@"multiline"]) {
BOOL mutilin = [(NSNumber *) prop boolValue];
if (!mutilin) {
view.textContainer.maximumNumberOfLines = 1;
}else {
view.textContainer.maximumNumberOfLines = 0;
}
} else if ([name isEqualToString:@"hintText"]) {
2020-05-06 15:11:57 +08:00
view.placeholderLabel.text = (NSString *)prop;
2019-12-11 14:14:20 +08:00
} else if ([name isEqualToString:@"hintTextColor"]) {
2020-05-06 15:11:57 +08:00
view.placeholderLabel.textColor = DoricColor(prop);
2019-12-11 14:14:20 +08:00
} else if ([name isEqualToString:@"onTextChange"]) {
if ([prop isKindOfClass:[NSString class]]) {
self.onTextChange = ^(NSString *text, DoricInputNode *node) {
[node callJSResponse:prop,text,nil];
};
}else {
self.onTextChange = nil;
}
} else if ([name isEqualToString:@"onFocusChange"]) {
if ([prop isKindOfClass:[NSString class]]) {
self.onFocusShange = ^(BOOL focused, DoricInputNode *node) {
[node callJSResponse:prop,@(focused),nil];
};
}else {
self.onFocusShange = nil;
}
2020-04-30 18:31:26 +08:00
} else if ([name isEqualToString:@"maxLength"]) {
self.maxLength = prop;
} 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-05-06 15:11:57 +08:00
- (void)afterBlended:(NSDictionary *)props {
[super afterBlended:props];
if (self.view.doricLayout.paddingTop != self.view.textContainerInset.top
|| self.view.doricLayout.paddingLeft != self.view.textContainerInset.left
|| self.view.doricLayout.paddingBottom != self.view.textContainerInset.bottom
|| self.view.doricLayout.paddingRight != self.view.textContainerInset.right) {
self.view.textContainerInset = UIEdgeInsetsMake(self.view.doricLayout.paddingTop, self.view.doricLayout.paddingLeft, self.view.doricLayout.paddingBottom, self.view.doricLayout.paddingRight);
}
self.view.placeholderLabel.font = self.view.font;
self.view.placeholderLabel.numberOfLines = self.view.textContainer.maximumNumberOfLines;
}
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
- (NSString *)getText {
return self.view.text;
}
- (void)setSelection:(NSDictionary *)params withPromise:(DoricPromise *)promise {
2019-12-11 14:29:29 +08:00
NSString *start = params[@"start"];
NSString *end = params[@"end"];
2019-12-11 14:14:20 +08:00
if (([start isKindOfClass:[NSString class]] || [start isKindOfClass:[NSNumber class]]) &&
([start isKindOfClass:[NSString class]] || [start isKindOfClass:[NSNumber class]])) {
self.view.selectedRange = NSMakeRange(start.intValue, end.intValue - start.intValue);
}
[promise resolve:nil];
}
- (void)requestFocus {
[self.view becomeFirstResponder];
}
- (void)releaseFocus {
[self.view resignFirstResponder];
}
#pragma mark - UITextViewDelegate
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
if (self.onFocusShange) {
self.onFocusShange(YES, self);
}
return YES;
}
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
if (self.onFocusShange) {
self.onFocusShange(NO, self);
}
return YES;
}
- (void)textViewDidChange:(UITextView *)textView {
2020-04-30 18:31:26 +08:00
if (self.maxLength) {
if (textView.text.length > self.maxLength.unsignedIntValue) {
2020-05-08 15:51:00 +08:00
NSRange range = [textView.text rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, self.maxLength.unsignedIntValue)];
textView.text = [textView.text substringWithRange: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
}
@end