mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
[ASEditableTextNode] Support UITextInputTraits pass-through methods (threadsafe for use before view creation) (#1809)
* [ASEditableTextNode] Support UITextInputTraits * consistent property attributes * remove logging, fix tests to account for UIKit weirdness * address @appleguy's comments
This commit is contained in:
@@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@abstract Implements a node that supports text editing.
|
@abstract Implements a node that supports text editing.
|
||||||
@discussion Does not support layer backing.
|
@discussion Does not support layer backing.
|
||||||
*/
|
*/
|
||||||
@interface ASEditableTextNode : ASDisplayNode
|
@interface ASEditableTextNode : ASDisplayNode <UITextInputTraits>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Initializes an editable text node using default TextKit components.
|
* @abstract Initializes an editable text node using default TextKit components.
|
||||||
@@ -93,9 +93,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@property (nonatomic, readwrite) UIEdgeInsets textContainerInset;
|
@property (nonatomic, readwrite) UIEdgeInsets textContainerInset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@abstract The returnKeyType of the keyboard. This value defaults to UIReturnKeyDefault.
|
@abstract <UITextInputTraits> properties.
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, readwrite) UIReturnKeyType returnKeyType;
|
@property(nonatomic, readwrite, assign) UITextAutocapitalizationType autocapitalizationType; // default is UITextAutocapitalizationTypeSentences
|
||||||
|
@property(nonatomic, readwrite, assign) UITextAutocorrectionType autocorrectionType; // default is UITextAutocorrectionTypeDefault
|
||||||
|
@property(nonatomic, readwrite, assign) UITextSpellCheckingType spellCheckingType; // default is UITextSpellCheckingTypeDefault;
|
||||||
|
@property(nonatomic, readwrite, assign) UIKeyboardType keyboardType; // default is UIKeyboardTypeDefault
|
||||||
|
@property(nonatomic, readwrite, assign) UIKeyboardAppearance keyboardAppearance; // default is UIKeyboardAppearanceDefault
|
||||||
|
@property(nonatomic, readwrite, assign) UIReturnKeyType returnKeyType; // default is UIReturnKeyDefault (See note under UIReturnKeyType enum)
|
||||||
|
@property(nonatomic, readwrite, assign) BOOL enablesReturnKeyAutomatically; // default is NO (when YES, will automatically disable return key when text widget has zero-length contents, and will automatically enable when text widget has non-zero-length contents)
|
||||||
|
@property(nonatomic, readwrite, assign, getter=isSecureTextEntry) BOOL secureTextEntry; // default is NO
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@abstract Indicates whether the receiver's text view is the first responder, and thus has the keyboard visible and is prepared for editing by the user.
|
@abstract Indicates whether the receiver's text view is the first responder, and thus has the keyboard visible and is prepared for editing by the user.
|
||||||
|
|||||||
@@ -17,6 +17,42 @@
|
|||||||
#import "ASTextNodeWordKerner.h"
|
#import "ASTextNodeWordKerner.h"
|
||||||
#import "ASThread.h"
|
#import "ASThread.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
@abstract Object to hold UITextView's pending UITextInputTraits
|
||||||
|
**/
|
||||||
|
@interface _ASTextInputTraitsPendingState : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, readwrite, assign) UITextAutocapitalizationType autocapitalizationType;
|
||||||
|
@property (nonatomic, readwrite, assign) UITextAutocorrectionType autocorrectionType;
|
||||||
|
@property (nonatomic, readwrite, assign) UITextSpellCheckingType spellCheckingType;
|
||||||
|
@property (nonatomic, readwrite, assign) UIKeyboardAppearance keyboardAppearance;
|
||||||
|
@property (nonatomic, readwrite, assign) UIKeyboardType keyboardType;
|
||||||
|
@property (nonatomic, readwrite, assign) UIReturnKeyType returnKeyType;
|
||||||
|
@property (nonatomic, readwrite, assign) BOOL enablesReturnKeyAutomatically;
|
||||||
|
@property (nonatomic, readwrite, assign, getter=isSecureTextEntry) BOOL secureTextEntry;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation _ASTextInputTraitsPendingState
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
if (!(self = [super init]))
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
// set default values, as defined in Apple's comments in UITextInputTraits.h
|
||||||
|
_autocapitalizationType = UITextAutocapitalizationTypeSentences;
|
||||||
|
_autocorrectionType = UITextAutocorrectionTypeDefault;
|
||||||
|
_spellCheckingType = UITextSpellCheckingTypeDefault;
|
||||||
|
_keyboardAppearance = UIKeyboardAppearanceDefault;
|
||||||
|
_keyboardType = UIKeyboardTypeDefault;
|
||||||
|
_returnKeyType = UIReturnKeyDefault;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@abstract As originally reported in rdar://14729288, when scrollEnabled = NO,
|
@abstract As originally reported in rdar://14729288, when scrollEnabled = NO,
|
||||||
UITextView does not calculate its contentSize. This makes it difficult
|
UITextView does not calculate its contentSize. This makes it difficult
|
||||||
@@ -85,6 +121,10 @@
|
|||||||
ASTextKitComponents *_placeholderTextKitComponents;
|
ASTextKitComponents *_placeholderTextKitComponents;
|
||||||
// Forwards NSLayoutManagerDelegate methods related to word kerning
|
// Forwards NSLayoutManagerDelegate methods related to word kerning
|
||||||
ASTextNodeWordKerner *_wordKerner;
|
ASTextNodeWordKerner *_wordKerner;
|
||||||
|
|
||||||
|
// UITextInputTraits
|
||||||
|
ASDN::RecursiveMutex _textInputTraitsLock;
|
||||||
|
_ASTextInputTraitsPendingState *_textInputTraits;
|
||||||
|
|
||||||
// Misc. State.
|
// Misc. State.
|
||||||
BOOL _displayingPlaceholder; // Defaults to YES.
|
BOOL _displayingPlaceholder; // Defaults to YES.
|
||||||
@@ -93,6 +133,8 @@
|
|||||||
NSRange _previousSelectedRange;
|
NSRange _previousSelectedRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) _ASTextInputTraitsPendingState *textInputTraits;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation ASEditableTextNode
|
@implementation ASEditableTextNode
|
||||||
@@ -117,13 +159,12 @@
|
|||||||
_textKitComponents = textKitComponents;
|
_textKitComponents = textKitComponents;
|
||||||
_textKitComponents.layoutManager.delegate = self;
|
_textKitComponents.layoutManager.delegate = self;
|
||||||
_wordKerner = [[ASTextNodeWordKerner alloc] init];
|
_wordKerner = [[ASTextNodeWordKerner alloc] init];
|
||||||
_returnKeyType = UIReturnKeyDefault;
|
|
||||||
_textContainerInset = UIEdgeInsetsZero;
|
_textContainerInset = UIEdgeInsetsZero;
|
||||||
|
|
||||||
// Create the placeholder scaffolding.
|
// Create the placeholder scaffolding.
|
||||||
_placeholderTextKitComponents = placeholderTextKitComponents;
|
_placeholderTextKitComponents = placeholderTextKitComponents;
|
||||||
_placeholderTextKitComponents.layoutManager.delegate = self;
|
_placeholderTextKitComponents.layoutManager.delegate = self;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,8 +192,6 @@
|
|||||||
{
|
{
|
||||||
[super didLoad];
|
[super didLoad];
|
||||||
|
|
||||||
ASDN::MutexLocker l(_textKitLock);
|
|
||||||
|
|
||||||
void (^configureTextView)(UITextView *) = ^(UITextView *textView) {
|
void (^configureTextView)(UITextView *) = ^(UITextView *textView) {
|
||||||
if (!_displayingPlaceholder || textView != _textKitComponents.textView) {
|
if (!_displayingPlaceholder || textView != _textKitComponents.textView) {
|
||||||
// If showing the placeholder, don't propagate backgroundColor/opaque to the editable textView. It is positioned over the placeholder to accept taps to begin editing, and if it's opaque/colored then it'll obscure the placeholder.
|
// If showing the placeholder, don't propagate backgroundColor/opaque to the editable textView. It is positioned over the placeholder to accept taps to begin editing, and if it's opaque/colored then it'll obscure the placeholder.
|
||||||
@@ -164,28 +203,48 @@
|
|||||||
textView.opaque = NO;
|
textView.opaque = NO;
|
||||||
}
|
}
|
||||||
textView.textContainerInset = self.textContainerInset;
|
textView.textContainerInset = self.textContainerInset;
|
||||||
|
|
||||||
|
// Configure textView with UITextInputTraits
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (_textInputTraits) {
|
||||||
|
textView.autocapitalizationType = _textInputTraits.autocapitalizationType;
|
||||||
|
textView.autocorrectionType = _textInputTraits.autocorrectionType;
|
||||||
|
textView.spellCheckingType = _textInputTraits.spellCheckingType;
|
||||||
|
textView.keyboardType = _textInputTraits.keyboardType;
|
||||||
|
textView.keyboardAppearance = _textInputTraits.keyboardAppearance;
|
||||||
|
textView.returnKeyType = _textInputTraits.returnKeyType;
|
||||||
|
textView.enablesReturnKeyAutomatically = _textInputTraits.enablesReturnKeyAutomatically;
|
||||||
|
textView.secureTextEntry = _textInputTraits.isSecureTextEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[self.view addSubview:textView];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ASDN::MutexLocker l(_textKitLock);
|
||||||
|
|
||||||
// Create and configure the placeholder text view.
|
// Create and configure the placeholder text view.
|
||||||
_placeholderTextKitComponents.textView = [[UITextView alloc] initWithFrame:CGRectZero textContainer:_placeholderTextKitComponents.textContainer];
|
_placeholderTextKitComponents.textView = [[UITextView alloc] initWithFrame:CGRectZero textContainer:_placeholderTextKitComponents.textContainer];
|
||||||
_placeholderTextKitComponents.textView.userInteractionEnabled = NO;
|
_placeholderTextKitComponents.textView.userInteractionEnabled = NO;
|
||||||
_placeholderTextKitComponents.textView.accessibilityElementsHidden = YES;
|
_placeholderTextKitComponents.textView.accessibilityElementsHidden = YES;
|
||||||
configureTextView(_placeholderTextKitComponents.textView);
|
configureTextView(_placeholderTextKitComponents.textView);
|
||||||
[self.view addSubview:_placeholderTextKitComponents.textView];
|
|
||||||
|
|
||||||
// Create and configure our text view.
|
// Create and configure our text view.
|
||||||
_textKitComponents.textView = self.textView;
|
_textKitComponents.textView = [[ASPanningOverriddenUITextView alloc] initWithFrame:CGRectZero textContainer:_textKitComponents.textContainer];
|
||||||
_textKitComponents.textView.scrollEnabled = _scrollEnabled;
|
_textKitComponents.textView.scrollEnabled = _scrollEnabled;
|
||||||
_textKitComponents.textView.delegate = self;
|
_textKitComponents.textView.delegate = self;
|
||||||
#if TARGET_OS_IOS
|
#if TARGET_OS_IOS
|
||||||
_textKitComponents.textView.editable = YES;
|
_textKitComponents.textView.editable = YES;
|
||||||
#endif
|
#endif
|
||||||
_textKitComponents.textView.typingAttributes = _typingAttributes;
|
_textKitComponents.textView.typingAttributes = _typingAttributes;
|
||||||
_textKitComponents.textView.returnKeyType = _returnKeyType;
|
|
||||||
_textKitComponents.textView.accessibilityHint = _placeholderTextKitComponents.textStorage.string;
|
_textKitComponents.textView.accessibilityHint = _placeholderTextKitComponents.textStorage.string;
|
||||||
configureTextView(_textKitComponents.textView);
|
configureTextView(_textKitComponents.textView);
|
||||||
[self.view addSubview:_textKitComponents.textView];
|
|
||||||
[self _updateDisplayingPlaceholder];
|
[self _updateDisplayingPlaceholder];
|
||||||
|
|
||||||
|
// once view is loaded, setters set directly on view
|
||||||
|
_textInputTraits = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||||
@@ -261,9 +320,8 @@
|
|||||||
- (UITextView *)textView
|
- (UITextView *)textView
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
if (!_textKitComponents.textView) {
|
[self view];
|
||||||
_textKitComponents.textView = [[ASPanningOverriddenUITextView alloc] initWithFrame:CGRectZero textContainer:_textKitComponents.textContainer];
|
ASDisplayNodeAssert(_textKitComponents.textView != nil, @"UITextView must be created in -[ASEditableTextNode didLoad]");
|
||||||
}
|
|
||||||
return _textKitComponents.textView;
|
return _textKitComponents.textView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,13 +483,6 @@
|
|||||||
return [_textKitComponents.textView textInputMode];
|
return [_textKitComponents.textView textInputMode];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setReturnKeyType:(UIReturnKeyType)returnKeyType
|
|
||||||
{
|
|
||||||
ASDN::MutexLocker l(_textKitLock);
|
|
||||||
_returnKeyType = returnKeyType;
|
|
||||||
[_textKitComponents.textView setReturnKeyType:_returnKeyType];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isFirstResponder
|
- (BOOL)isFirstResponder
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_textKitLock);
|
ASDN::MutexLocker l(_textKitLock);
|
||||||
@@ -460,6 +511,176 @@
|
|||||||
return [_textKitComponents.textView resignFirstResponder];
|
return [_textKitComponents.textView resignFirstResponder];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - UITextInputTraits
|
||||||
|
|
||||||
|
- (_ASTextInputTraitsPendingState *)textInputTraits
|
||||||
|
{
|
||||||
|
if (!_textInputTraits) {
|
||||||
|
_textInputTraits = [[_ASTextInputTraitsPendingState alloc] init];
|
||||||
|
}
|
||||||
|
return _textInputTraits;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAutocapitalizationType:(UITextAutocapitalizationType)autocapitalizationType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
[self.textView setAutocapitalizationType:autocapitalizationType];
|
||||||
|
} else {
|
||||||
|
[self.textInputTraits setAutocapitalizationType:autocapitalizationType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UITextAutocapitalizationType)autocapitalizationType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
return [self.textView autocapitalizationType];
|
||||||
|
} else {
|
||||||
|
return [self.textInputTraits autocapitalizationType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAutocorrectionType:(UITextAutocorrectionType)autocorrectionType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
[self.textView setAutocorrectionType:autocorrectionType];
|
||||||
|
} else {
|
||||||
|
[self.textInputTraits setAutocorrectionType:autocorrectionType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UITextAutocorrectionType)autocorrectionType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
return [self.textView autocorrectionType];
|
||||||
|
} else {
|
||||||
|
return [self.textInputTraits autocorrectionType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setSpellCheckingType:(UITextSpellCheckingType)spellCheckingType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
[self.textView setSpellCheckingType:spellCheckingType];
|
||||||
|
} else {
|
||||||
|
[self.textInputTraits setSpellCheckingType:spellCheckingType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UITextSpellCheckingType)spellCheckingType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
return [self.textView spellCheckingType];
|
||||||
|
} else {
|
||||||
|
return [self.textInputTraits spellCheckingType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setEnablesReturnKeyAutomatically:(BOOL)enablesReturnKeyAutomatically
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
[self.textView setEnablesReturnKeyAutomatically:enablesReturnKeyAutomatically];
|
||||||
|
} else {
|
||||||
|
[self.textInputTraits setEnablesReturnKeyAutomatically:enablesReturnKeyAutomatically];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)enablesReturnKeyAutomatically
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
return [self.textView enablesReturnKeyAutomatically];
|
||||||
|
} else {
|
||||||
|
return [self.textInputTraits enablesReturnKeyAutomatically];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setKeyboardAppearance:(UIKeyboardAppearance)setKeyboardAppearance
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
[self.textView setKeyboardAppearance:setKeyboardAppearance];
|
||||||
|
} else {
|
||||||
|
[self.textInputTraits setKeyboardAppearance:setKeyboardAppearance];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIKeyboardAppearance)keyboardAppearance
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
return [self.textView keyboardAppearance];
|
||||||
|
} else {
|
||||||
|
return [self.textInputTraits keyboardAppearance];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setKeyboardType:(UIKeyboardType)keyboardType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
[self.textView setKeyboardType:keyboardType];
|
||||||
|
} else {
|
||||||
|
[self.textInputTraits setKeyboardType:keyboardType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIKeyboardType)keyboardType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
return [self.textView keyboardType];
|
||||||
|
} else {
|
||||||
|
return [self.textInputTraits keyboardType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setReturnKeyType:(UIReturnKeyType)returnKeyType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
[self.textView setReturnKeyType:returnKeyType];
|
||||||
|
} else {
|
||||||
|
[self.textInputTraits setReturnKeyType:returnKeyType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIReturnKeyType)returnKeyType
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
return [self.textView returnKeyType];
|
||||||
|
} else {
|
||||||
|
return [self.textInputTraits returnKeyType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setSecureTextEntry:(BOOL)secureTextEntry
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
[self.textView setSecureTextEntry:secureTextEntry];
|
||||||
|
} else {
|
||||||
|
[self.textInputTraits setSecureTextEntry:secureTextEntry];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isSecureTextEntry
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_textInputTraitsLock);
|
||||||
|
if (self.isNodeLoaded) {
|
||||||
|
return [self.textView isSecureTextEntry];
|
||||||
|
} else {
|
||||||
|
return [self.textInputTraits isSecureTextEntry];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - UITextView Delegate
|
#pragma mark - UITextView Delegate
|
||||||
- (void)textViewDidBeginEditing:(UITextView *)textView
|
- (void)textViewDidBeginEditing:(UITextView *)textView
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ static BOOL CGSizeEqualToSizeWithIn(CGSize size1, CGSize size2, CGFloat delta)
|
|||||||
|
|
||||||
_attributedText = mas;
|
_attributedText = mas;
|
||||||
_editableTextNode.attributedText = _attributedText;
|
_editableTextNode.attributedText = _attributedText;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - ASEditableTextNode
|
#pragma mark - ASEditableTextNode
|
||||||
@@ -55,10 +54,89 @@ static BOOL CGSizeEqualToSizeWithIn(CGSize size1, CGSize size2, CGFloat delta)
|
|||||||
- (void)testAllocASEditableTextNode
|
- (void)testAllocASEditableTextNode
|
||||||
{
|
{
|
||||||
ASEditableTextNode *node = [[ASEditableTextNode alloc] init];
|
ASEditableTextNode *node = [[ASEditableTextNode alloc] init];
|
||||||
XCTAssertTrue([[node class] isSubclassOfClass:[ASEditableTextNode class]], @"ASTextNode alloc should return an instance of ASTextNode, instead returned %@", [node class]);
|
XCTAssertTrue([[node class] isSubclassOfClass:[ASEditableTextNode class]], @"ASEditableTextNode alloc should return an instance of ASEditableTextNode, instead returned %@", [node class]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - ASEditableTextNode
|
#pragma mark - ASEditableTextNode Tests
|
||||||
|
|
||||||
|
- (void)testUITextInputTraitDefaults
|
||||||
|
{
|
||||||
|
ASEditableTextNode *editableTextNode = [[ASEditableTextNode alloc] init];
|
||||||
|
|
||||||
|
XCTAssertTrue(editableTextNode.autocapitalizationType == UITextAutocapitalizationTypeSentences, @"_ASTextInputTraitsPendingState's autocapitalizationType default should be UITextAutocapitalizationTypeSentences.");
|
||||||
|
XCTAssertTrue(editableTextNode.autocorrectionType == UITextAutocorrectionTypeDefault, @"_ASTextInputTraitsPendingState's autocorrectionType default should be UITextAutocorrectionTypeDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.spellCheckingType == UITextSpellCheckingTypeDefault, @"_ASTextInputTraitsPendingState's spellCheckingType default should be UITextSpellCheckingTypeDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.keyboardType == UIKeyboardTypeDefault, @"_ASTextInputTraitsPendingState's keyboardType default should be UIKeyboardTypeDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.keyboardAppearance == UIKeyboardAppearanceDefault, @"_ASTextInputTraitsPendingState's keyboardAppearance default should be UIKeyboardAppearanceDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.returnKeyType == UIReturnKeyDefault, @"_ASTextInputTraitsPendingState's returnKeyType default should be UIReturnKeyDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.enablesReturnKeyAutomatically == NO, @"_ASTextInputTraitsPendingState's enablesReturnKeyAutomatically default should be NO.");
|
||||||
|
XCTAssertTrue(editableTextNode.isSecureTextEntry == NO, @"_ASTextInputTraitsPendingState's isSecureTextEntry default should be NO.");
|
||||||
|
|
||||||
|
XCTAssertTrue(editableTextNode.textView.autocapitalizationType == UITextAutocapitalizationTypeSentences, @"textView's autocapitalizationType default should be UITextAutocapitalizationTypeSentences.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.autocorrectionType == UITextAutocorrectionTypeDefault, @"textView's autocorrectionType default should be UITextAutocorrectionTypeDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.spellCheckingType == UITextSpellCheckingTypeDefault, @"textView's spellCheckingType default should be UITextSpellCheckingTypeDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.keyboardType == UIKeyboardTypeDefault, @"textView's keyboardType default should be UIKeyboardTypeDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.keyboardAppearance == UIKeyboardAppearanceDefault, @"textView's keyboardAppearance default should be UIKeyboardAppearanceDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.returnKeyType == UIReturnKeyDefault, @"textView's returnKeyType default should be UIReturnKeyDefault.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.enablesReturnKeyAutomatically == NO, @"textView's enablesReturnKeyAutomatically default should be NO.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.isSecureTextEntry == NO, @"textView's isSecureTextEntry default should be NO.");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testUITextInputTraitsSetTraitsBeforeViewLoaded
|
||||||
|
{
|
||||||
|
// UITextView ignores any values set on the first 3 properties below if secureTextEntry is enabled.
|
||||||
|
// Because of this UIKit behavior, we'll test secure entry seperately
|
||||||
|
ASEditableTextNode *editableTextNode = [[ASEditableTextNode alloc] init];
|
||||||
|
|
||||||
|
editableTextNode.autocapitalizationType = UITextAutocapitalizationTypeWords;
|
||||||
|
editableTextNode.autocorrectionType = UITextAutocorrectionTypeYes;
|
||||||
|
editableTextNode.spellCheckingType = UITextSpellCheckingTypeYes;
|
||||||
|
editableTextNode.keyboardType = UIKeyboardTypeTwitter;
|
||||||
|
editableTextNode.keyboardAppearance = UIKeyboardAppearanceDark;
|
||||||
|
editableTextNode.returnKeyType = UIReturnKeyGo;
|
||||||
|
editableTextNode.enablesReturnKeyAutomatically = YES;
|
||||||
|
|
||||||
|
XCTAssertTrue(editableTextNode.textView.autocapitalizationType == UITextAutocapitalizationTypeWords, @"textView's autocapitalizationType should be UITextAutocapitalizationTypeAllCharacters.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.autocorrectionType == UITextAutocorrectionTypeYes, @"textView's autocorrectionType should be UITextAutocorrectionTypeYes.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.spellCheckingType == UITextSpellCheckingTypeYes, @"textView's spellCheckingType should be UITextSpellCheckingTypeYes.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.keyboardType == UIKeyboardTypeTwitter, @"textView's keyboardType should be UIKeyboardTypeTwitter.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.keyboardAppearance == UIKeyboardAppearanceDark, @"textView's keyboardAppearance should be UIKeyboardAppearanceDark.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.returnKeyType == UIReturnKeyGo, @"textView's returnKeyType should be UIReturnKeyGo.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.enablesReturnKeyAutomatically == YES, @"textView's enablesReturnKeyAutomatically should be YES.");
|
||||||
|
|
||||||
|
ASEditableTextNode *secureEditableTextNode = [[ASEditableTextNode alloc] init];
|
||||||
|
secureEditableTextNode.secureTextEntry = YES;
|
||||||
|
|
||||||
|
XCTAssertTrue(secureEditableTextNode.textView.secureTextEntry == YES, @"textView's isSecureTextEntry should be YES.");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testUITextInputTraitsChangeTraitAfterViewLoaded
|
||||||
|
{
|
||||||
|
// UITextView ignores any values set on the first 3 properties below if secureTextEntry is enabled.
|
||||||
|
// Because of this UIKit behavior, we'll test secure entry seperately
|
||||||
|
ASEditableTextNode *editableTextNode = [[ASEditableTextNode alloc] init];
|
||||||
|
|
||||||
|
editableTextNode.textView.autocapitalizationType = UITextAutocapitalizationTypeWords;
|
||||||
|
editableTextNode.textView.autocorrectionType = UITextAutocorrectionTypeYes;
|
||||||
|
editableTextNode.textView.spellCheckingType = UITextSpellCheckingTypeYes;
|
||||||
|
editableTextNode.textView.keyboardType = UIKeyboardTypeTwitter;
|
||||||
|
editableTextNode.textView.keyboardAppearance = UIKeyboardAppearanceDark;
|
||||||
|
editableTextNode.textView.returnKeyType = UIReturnKeyGo;
|
||||||
|
editableTextNode.textView.enablesReturnKeyAutomatically = YES;
|
||||||
|
|
||||||
|
XCTAssertTrue(editableTextNode.textView.autocapitalizationType == UITextAutocapitalizationTypeWords, @"textView's autocapitalizationType should be UITextAutocapitalizationTypeAllCharacters.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.autocorrectionType == UITextAutocorrectionTypeYes, @"textView's autocorrectionType should be UITextAutocorrectionTypeYes.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.spellCheckingType == UITextSpellCheckingTypeYes, @"textView's spellCheckingType should be UITextSpellCheckingTypeYes.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.keyboardType == UIKeyboardTypeTwitter, @"textView's keyboardType should be UIKeyboardTypeTwitter.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.keyboardAppearance == UIKeyboardAppearanceDark, @"textView's keyboardAppearance should be UIKeyboardAppearanceDark.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.returnKeyType == UIReturnKeyGo, @"textView's returnKeyType should be UIReturnKeyGo.");
|
||||||
|
XCTAssertTrue(editableTextNode.textView.enablesReturnKeyAutomatically == YES, @"textView's enablesReturnKeyAutomatically should be YES.");
|
||||||
|
|
||||||
|
ASEditableTextNode *secureEditableTextNode = [[ASEditableTextNode alloc] init];
|
||||||
|
secureEditableTextNode.textView.secureTextEntry = YES;
|
||||||
|
|
||||||
|
XCTAssertTrue(secureEditableTextNode.textView.secureTextEntry == YES, @"textView's isSecureTextEntry should be YES.");
|
||||||
|
}
|
||||||
|
|
||||||
- (void)testSetPreferredFrameSize
|
- (void)testSetPreferredFrameSize
|
||||||
{
|
{
|
||||||
@@ -66,8 +144,8 @@ static BOOL CGSizeEqualToSizeWithIn(CGSize size1, CGSize size2, CGFloat delta)
|
|||||||
_editableTextNode.preferredFrameSize = preferredFrameSize;
|
_editableTextNode.preferredFrameSize = preferredFrameSize;
|
||||||
|
|
||||||
CGSize calculatedSize = [_editableTextNode measure:CGSizeZero];
|
CGSize calculatedSize = [_editableTextNode measure:CGSizeZero];
|
||||||
XCTAssertTrue(calculatedSize.width != preferredFrameSize.width, @"Calculated width (%f) should be equal than preferred width (%f)", calculatedSize.width, preferredFrameSize.width);
|
XCTAssertTrue(calculatedSize.width != preferredFrameSize.width, @"Calculated width (%f) should be equal to preferred width (%f)", calculatedSize.width, preferredFrameSize.width);
|
||||||
XCTAssertTrue(calculatedSize.width != preferredFrameSize.width, @"Calculated height (%f) should be equal than preferred height (%f)", calculatedSize.width, preferredFrameSize.width);
|
XCTAssertTrue(calculatedSize.width != preferredFrameSize.width, @"Calculated height (%f) should be equal to preferred height (%f)", calculatedSize.width, preferredFrameSize.width);
|
||||||
|
|
||||||
_editableTextNode.preferredFrameSize = CGSizeZero;
|
_editableTextNode.preferredFrameSize = CGSizeZero;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user