mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
1066 lines
39 KiB
Objective-C
1066 lines
39 KiB
Objective-C
#import "TGMediaPickerCaptionInputPanel.h"
|
|
|
|
#import "TGMessage.h"
|
|
#import "TGInputTextTag.h"
|
|
|
|
#import "LegacyComponentsInternal.h"
|
|
#import "TGImageUtils.h"
|
|
#import "TGFont.h"
|
|
#import "TGViewController.h"
|
|
#import "TGHacks.h"
|
|
#import "TGModernButton.h"
|
|
|
|
#import "TGPhotoEditorInterfaceAssets.h"
|
|
#import "TGMediaAssetsController.h"
|
|
|
|
#import "HPTextViewInternal.h"
|
|
|
|
#import "TGModernConversationAssociatedInputPanel.h"
|
|
|
|
const NSInteger TGMediaPickerCaptionInputPanelCaptionLimit = 1024;
|
|
|
|
static void setViewFrame(UIView *view, CGRect frame)
|
|
{
|
|
CGAffineTransform transform = view.transform;
|
|
view.transform = CGAffineTransformIdentity;
|
|
if (!CGRectEqualToRect(view.frame, frame))
|
|
view.frame = frame;
|
|
view.transform = transform;
|
|
}
|
|
|
|
@interface TGMediaPickerCaptionInputPanel () <HPGrowingTextViewDelegate>
|
|
{
|
|
CGFloat _keyboardHeight;
|
|
NSString *_caption;
|
|
bool _dismissing;
|
|
bool _dismissDisabled;
|
|
|
|
NSArray *_entities;
|
|
|
|
UIView *_wrapperView;
|
|
UIView *_backgroundView;
|
|
UIImageView *_fieldBackground;
|
|
UIView *_inputFieldClippingContainer;
|
|
HPGrowingTextView *_inputField;
|
|
UILabel *_placeholderLabel;
|
|
|
|
UIView *_doneButtonWrapper;
|
|
TGModernButton *_doneButton;
|
|
|
|
UILabel *_inputFieldOnelineLabel;
|
|
|
|
UILabel *_counterLabel;
|
|
|
|
TGModernConversationAssociatedInputPanel *_associatedPanel;
|
|
|
|
CGFloat _contentAreaHeight;
|
|
|
|
__weak TGKeyCommandController *_keyCommandController;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation TGMediaPickerCaptionInputPanel
|
|
|
|
- (instancetype)initWithKeyCommandController:(TGKeyCommandController *)keyCommandController frame:(CGRect)frame
|
|
{
|
|
self = [super initWithFrame:frame];
|
|
if (self != nil)
|
|
{
|
|
_keyCommandController = keyCommandController;
|
|
static UIImage *fieldBackgroundImage = nil;
|
|
static UIImage *placeholderImage = nil;
|
|
|
|
static NSString *localizationPlaceholderText = nil;
|
|
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
UIGraphicsBeginImageContextWithOptions(CGSizeMake(33, 33), false, 0.0f);
|
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
CGContextSetFillColorWithColor(context, UIColorRGBA(0xffffff, 0.1f).CGColor);
|
|
|
|
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 33, 33) cornerRadius:16.5f];
|
|
[path fill];
|
|
|
|
fieldBackgroundImage = [UIGraphicsGetImageFromCurrentImageContext() resizableImageWithCapInsets:UIEdgeInsetsMake(16, 16, 16, 16)];
|
|
UIGraphicsEndImageContext();
|
|
});
|
|
|
|
if (placeholderImage == nil || localizationPlaceholderText != TGLocalized(@"MediaPicker.AddCaption"))
|
|
{
|
|
localizationPlaceholderText = TGLocalized(@"MediaPicker.AddCaption");
|
|
NSString *placeholderText = TGLocalized(@"MediaPicker.AddCaption");
|
|
UIFont *placeholderFont = TGSystemFontOfSize(17);
|
|
CGSize placeholderSize = [placeholderText sizeWithFont:placeholderFont];
|
|
placeholderSize.width += 2.0f;
|
|
placeholderSize.height += 2.0f;
|
|
|
|
UIGraphicsBeginImageContextWithOptions(placeholderSize, false, 0.0f);
|
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
CGContextSetFillColorWithColor(context, UIColorRGB(0xffffff).CGColor);
|
|
[placeholderText drawAtPoint:CGPointMake(1.0f, 1.0f) withFont:placeholderFont];
|
|
placeholderImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
UIGraphicsEndImageContext();
|
|
}
|
|
|
|
UIView *backgroundWrapperView = [[UIView alloc] initWithFrame:frame];
|
|
backgroundWrapperView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
backgroundWrapperView.clipsToBounds = true;
|
|
[self addSubview:backgroundWrapperView];
|
|
|
|
_wrapperView = [[UIView alloc] initWithFrame:frame];
|
|
_wrapperView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
[self addSubview:_wrapperView];
|
|
|
|
_backgroundView = [[UIView alloc] initWithFrame:_wrapperView.bounds];
|
|
_backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
_backgroundView.backgroundColor = [TGPhotoEditorInterfaceAssets toolbarTransparentBackgroundColor];
|
|
[backgroundWrapperView addSubview:_backgroundView];
|
|
|
|
_fieldBackground = [[UIImageView alloc] initWithImage:fieldBackgroundImage];
|
|
_fieldBackground.alpha = 0.0f;
|
|
_fieldBackground.userInteractionEnabled = true;
|
|
[_wrapperView addSubview:_fieldBackground];
|
|
|
|
_placeholderLabel = [[UILabel alloc] init];
|
|
_placeholderLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
|
|
_placeholderLabel.backgroundColor = [UIColor clearColor];
|
|
_placeholderLabel.font = TGSystemFontOfSize(17);
|
|
_placeholderLabel.textColor = UIColorRGB(0x7f7f7f);
|
|
_placeholderLabel.text = TGLocalized(@"MediaPicker.AddCaption");
|
|
_placeholderLabel.userInteractionEnabled = true;
|
|
[_placeholderLabel sizeToFit];
|
|
[_wrapperView addSubview:_placeholderLabel];
|
|
|
|
_inputFieldOnelineLabel = [[UILabel alloc] init];
|
|
_inputFieldOnelineLabel.backgroundColor = [UIColor clearColor];
|
|
_inputFieldOnelineLabel.font = TGSystemFontOfSize(17);
|
|
_inputFieldOnelineLabel.hidden = true;
|
|
_inputFieldOnelineLabel.numberOfLines = 1;
|
|
_inputFieldOnelineLabel.textColor = [UIColor whiteColor];
|
|
_inputFieldOnelineLabel.userInteractionEnabled = false;
|
|
[_wrapperView addSubview:_inputFieldOnelineLabel];
|
|
|
|
_counterLabel = [[UILabel alloc] initWithFrame:CGRectMake(_fieldBackground.frame.size.width - 45, 5, 36, 16)];
|
|
_counterLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
|
|
_counterLabel.backgroundColor = [UIColor clearColor];
|
|
_counterLabel.font = TGSystemFontOfSize(12);
|
|
_counterLabel.hidden = true;
|
|
_counterLabel.textAlignment = NSTextAlignmentRight;
|
|
_counterLabel.textColor = UIColorRGB(0x828282);
|
|
_counterLabel.highlightedTextColor = UIColorRGB(0xff4848);
|
|
_counterLabel.userInteractionEnabled = false;
|
|
[_fieldBackground addSubview:_counterLabel];
|
|
|
|
_doneButtonWrapper = [[UIView alloc] init];
|
|
_doneButtonWrapper.alpha = 0.0f;
|
|
_doneButtonWrapper.userInteractionEnabled = false;
|
|
[_wrapperView addSubview:_doneButtonWrapper];
|
|
|
|
CGSize buttonSize = CGSizeMake(49.0f, 49.0f);
|
|
_doneButton = [[TGModernButton alloc] initWithFrame:CGRectMake(0, 0, buttonSize.width, buttonSize.height)];
|
|
_doneButton.exclusiveTouch = true;
|
|
_doneButton.adjustsImageWhenHighlighted = false;
|
|
[_doneButton addTarget:self action:@selector(setButtonPressed) forControlEvents:UIControlEventTouchUpInside];
|
|
[_doneButtonWrapper addSubview:_doneButton];
|
|
|
|
TGMediaAssetsPallete *pallete = nil;
|
|
if ([[LegacyComponentsGlobals provider] respondsToSelector:@selector(mediaAssetsPallete)])
|
|
pallete = [[LegacyComponentsGlobals provider] mediaAssetsPallete];
|
|
|
|
UIImage *doneImage = pallete != nil ? pallete.doneIconImage : TGTintedImage([UIImage imageNamed:@"Editor/Commit"], [UIColor whiteColor]);
|
|
[_doneButton setImage:doneImage forState:UIControlStateNormal];
|
|
|
|
[_wrapperView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleFieldBackgroundTap:)]];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)createInputFieldIfNeeded
|
|
{
|
|
if (_inputField != nil)
|
|
return;
|
|
|
|
CGRect inputFieldClippingFrame = _fieldBackground.frame;
|
|
_inputFieldClippingContainer = [[UIView alloc] initWithFrame:inputFieldClippingFrame];
|
|
_inputFieldClippingContainer.clipsToBounds = true;
|
|
[_wrapperView addSubview:_inputFieldClippingContainer];
|
|
|
|
UIEdgeInsets inputFieldInternalEdgeInsets = [self _inputFieldInternalEdgeInsets];
|
|
_inputField = [[HPGrowingTextView alloc] initWithKeyCommandController:_keyCommandController];
|
|
_inputField.frame = CGRectMake(inputFieldInternalEdgeInsets.left, inputFieldInternalEdgeInsets.top + TGRetinaPixel, _inputFieldClippingContainer.frame.size.width - inputFieldInternalEdgeInsets.left - 36, _inputFieldClippingContainer.frame.size.height);
|
|
_inputField.textColor = [UIColor whiteColor];
|
|
_inputField.disableFormatting = !_allowEntities;
|
|
_inputField.placeholderView = _placeholderLabel;
|
|
_inputField.font = TGSystemFontOfSize(17);
|
|
_inputField.accentColor = UIColorRGB(0x78b1f9);
|
|
_inputField.clipsToBounds = true;
|
|
_inputField.backgroundColor = nil;
|
|
_inputField.opaque = false;
|
|
_inputField.showPlaceholderWhenFocussed = true;
|
|
_inputField.internalTextView.returnKeyType = UIReturnKeyDefault;
|
|
_inputField.internalTextView.backgroundColor = nil;
|
|
_inputField.internalTextView.opaque = false;
|
|
_inputField.internalTextView.contentMode = UIViewContentModeLeft;
|
|
if (iosMajorVersion() >= 7)
|
|
_inputField.internalTextView.keyboardAppearance = UIKeyboardAppearanceDark;
|
|
else
|
|
_inputField.internalTextView.keyboardAppearance = UIKeyboardAppearanceAlert;
|
|
_inputField.maxNumberOfLines = [self _maxNumberOfLinesForSize:CGSizeMake(320.0f, 480.0f)];
|
|
_inputField.delegate = self;
|
|
|
|
_inputField.internalTextView.scrollIndicatorInsets = UIEdgeInsetsMake(-inputFieldInternalEdgeInsets.top, 0, 5 - TGRetinaPixel, 0);
|
|
|
|
[_inputField setAttributedText:[TGMediaPickerCaptionInputPanel attributedStringForText:_caption entities:_entities fontSize:17.0f] keepFormatting:true animated:false];
|
|
|
|
[_inputFieldClippingContainer addSubview:_inputField];
|
|
}
|
|
|
|
- (void)setAllowEntities:(bool)allowEntities
|
|
{
|
|
_allowEntities = allowEntities;
|
|
_inputField.disableFormatting = !_allowEntities;
|
|
}
|
|
|
|
- (void)handleFieldBackgroundTap:(UITapGestureRecognizer *)__unused gestureRecognizer
|
|
{
|
|
bool shouldBecomeFirstResponder = true;
|
|
|
|
id<TGMediaPickerCaptionInputPanelDelegate> delegate = self.delegate;
|
|
if ([delegate respondsToSelector:@selector(inputPanelShouldBecomeFirstResponder:)])
|
|
shouldBecomeFirstResponder = [delegate inputPanelShouldBecomeFirstResponder:self];
|
|
|
|
if (!shouldBecomeFirstResponder || self.isCollapsed)
|
|
return;
|
|
|
|
[self createInputFieldIfNeeded];
|
|
_inputFieldClippingContainer.hidden = false;
|
|
_inputField.internalTextView.enableFirstResponder = true;
|
|
[_inputField.internalTextView becomeFirstResponder];
|
|
}
|
|
|
|
- (bool)setButtonPressed
|
|
{
|
|
if (_dismissDisabled)
|
|
return false;
|
|
|
|
if (_inputField.text.length > TGMediaPickerCaptionInputPanelCaptionLimit)
|
|
{
|
|
[self shakeControls];
|
|
return false;
|
|
}
|
|
|
|
if (_inputField.internalTextView.isFirstResponder)
|
|
[TGHacks applyCurrentKeyboardAutocorrectionVariant];
|
|
|
|
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithAttributedString:_inputField.text == nil ? [[NSAttributedString alloc] initWithString:@""] : _inputField.attributedText];
|
|
NSMutableString *usualString = [text.string mutableCopy];
|
|
int textLength = (int)text.length;
|
|
for (int i = 0; i < textLength; i++)
|
|
{
|
|
unichar c = [usualString characterAtIndex:i];
|
|
|
|
if (c == ' ' || c == '\t' || c == '\n')
|
|
{
|
|
[text deleteCharactersInRange:NSMakeRange(i, 1)];
|
|
[usualString deleteCharactersInRange:NSMakeRange(i, 1)];
|
|
i--;
|
|
textLength--;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
_inputField.internalTextView.attributedText = text;
|
|
|
|
__autoreleasing NSArray *entities = nil;
|
|
NSString *finalText = [_inputField textWithEntities:&entities];
|
|
|
|
id<TGMediaPickerCaptionInputPanelDelegate> delegate = self.delegate;
|
|
if ([delegate respondsToSelector:@selector(inputPanelRequestedSetCaption:text:entities:)])
|
|
[delegate inputPanelRequestedSetCaption:self text:finalText entities:entities];
|
|
|
|
_dismissing = true;
|
|
|
|
[_inputField.internalTextView resignFirstResponder];
|
|
|
|
return true;
|
|
}
|
|
|
|
- (void)dismiss
|
|
{
|
|
[self setButtonPressed];
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (void)setCollapsed:(bool)collapsed
|
|
{
|
|
[self setCollapsed:collapsed animated:false];
|
|
}
|
|
|
|
- (void)setCollapsed:(bool)collapsed animated:(bool)animated
|
|
{
|
|
_collapsed = collapsed;
|
|
|
|
void (^frameChangeBlock)(void) = ^
|
|
{
|
|
_backgroundView.frame = CGRectMake(_backgroundView.frame.origin.x,
|
|
collapsed ? self.frame.size.height : 0,
|
|
_backgroundView.frame.size.width, _backgroundView.frame.size.height);
|
|
_wrapperView.frame = CGRectMake(_wrapperView.frame.origin.x,
|
|
collapsed ? self.frame.size.height : 0,
|
|
_wrapperView.frame.size.width, _wrapperView.frame.size.height);
|
|
};
|
|
|
|
void (^visibilityChangeBlock)(void) = ^
|
|
{
|
|
CGFloat alpha = collapsed ? 0.0f : 1.0f;
|
|
_wrapperView.alpha = alpha;
|
|
};
|
|
|
|
if (animated)
|
|
{
|
|
[UIView animateWithDuration:0.3f delay:0.0f options:[TGViewController preferredAnimationCurve] << 16 animations:frameChangeBlock completion:nil];
|
|
[UIView animateWithDuration:0.25f delay:collapsed ? 0.0f : 0.05f options:kNilOptions animations:visibilityChangeBlock completion:nil];
|
|
}
|
|
else
|
|
{
|
|
frameChangeBlock();
|
|
visibilityChangeBlock();
|
|
}
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (void)adjustForOrientation:(UIInterfaceOrientation)orientation keyboardHeight:(CGFloat)keyboardHeight duration:(NSTimeInterval)duration animationCurve:(NSInteger)animationCurve
|
|
{
|
|
[self adjustForOrientation:orientation keyboardHeight:keyboardHeight duration:duration animationCurve:animationCurve completion:nil];
|
|
}
|
|
|
|
- (void)adjustForOrientation:(UIInterfaceOrientation)__unused orientation keyboardHeight:(CGFloat)keyboardHeight duration:(NSTimeInterval)duration animationCurve:(NSInteger)animationCurve completion:(void (^)(void))completion
|
|
{
|
|
_keyboardHeight = keyboardHeight;
|
|
|
|
void(^changeBlock)(void) = ^
|
|
{
|
|
bool isKeyboardVisible = (keyboardHeight > FLT_EPSILON);
|
|
CGFloat inputContainerHeight = [self heightForInputFieldHeight:[self isFirstResponder] ? _inputField.frame.size.height : 0];
|
|
CGSize screenSize = self.superview.frame.size;
|
|
|
|
if (isKeyboardVisible)
|
|
{
|
|
self.frame = CGRectMake(self.frame.origin.x, screenSize.height - keyboardHeight - inputContainerHeight, self.frame.size.width, inputContainerHeight + keyboardHeight - self.bottomMargin);
|
|
_backgroundView.backgroundColor = [TGPhotoEditorInterfaceAssets toolbarBackgroundColor];
|
|
}
|
|
else
|
|
{
|
|
self.frame = CGRectMake(self.frame.origin.x, screenSize.height - self.bottomMargin - inputContainerHeight, self.frame.size.width, inputContainerHeight);
|
|
_backgroundView.backgroundColor = [TGPhotoEditorInterfaceAssets toolbarTransparentBackgroundColor];
|
|
}
|
|
|
|
[self layoutSubviews];
|
|
};
|
|
|
|
void (^finishedBlock)(BOOL) = ^(__unused BOOL finished)
|
|
{
|
|
if (completion != nil)
|
|
completion();
|
|
};
|
|
|
|
if (duration > DBL_EPSILON)
|
|
{
|
|
[UIView animateWithDuration:duration delay:0.0f options:animationCurve animations:changeBlock completion:finishedBlock];
|
|
}
|
|
else
|
|
{
|
|
changeBlock();
|
|
finishedBlock(true);
|
|
}
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (NSString *)caption
|
|
{
|
|
return _caption;
|
|
}
|
|
|
|
- (void)setCaption:(NSString *)caption
|
|
{
|
|
[self setCaption:caption entities:nil animated:false];
|
|
}
|
|
|
|
- (void)setCaption:(NSString *)caption entities:(NSArray *)entities animated:(bool)animated
|
|
{
|
|
NSString *previousCaption = _caption;
|
|
_caption = caption;
|
|
_entities = entities;
|
|
|
|
if (animated)
|
|
{
|
|
_inputFieldOnelineLabel.attributedText = [self oneLinedCaptionForText:caption entities:entities];
|
|
|
|
if ([previousCaption isEqualToString:caption] || (previousCaption.length == 0 && caption.length == 0))
|
|
return;
|
|
|
|
UIView *snapshotView = nil;
|
|
UIView *snapshottedView = nil;
|
|
UIView *fadingInView = nil;
|
|
if (previousCaption.length > 0)
|
|
snapshottedView = _inputFieldOnelineLabel;
|
|
else
|
|
snapshottedView = _placeholderLabel;
|
|
|
|
snapshotView = [snapshottedView snapshotViewAfterScreenUpdates:false];
|
|
snapshotView.frame = snapshottedView.frame;
|
|
[snapshottedView.superview addSubview:snapshotView];
|
|
|
|
if (previousCaption.length > 0 && caption.length == 0)
|
|
fadingInView = _placeholderLabel;
|
|
else
|
|
fadingInView = _inputFieldOnelineLabel;
|
|
|
|
fadingInView.hidden = false;
|
|
fadingInView.alpha = 0.0f;
|
|
|
|
_placeholderLabel.hidden = (caption.length > 0);
|
|
|
|
[UIView animateWithDuration:0.3f delay:0.05f options:UIViewAnimationOptionCurveEaseInOut animations:^
|
|
{
|
|
fadingInView.alpha = 1.0f;
|
|
} completion:nil];
|
|
|
|
[UIView animateWithDuration:0.21f delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^
|
|
{
|
|
snapshotView.alpha = 0.0f;
|
|
_fieldBackground.alpha = _placeholderLabel.hidden ? 1.0f : 0.0f;
|
|
} completion:^(__unused BOOL finished)
|
|
{
|
|
[snapshotView removeFromSuperview];
|
|
}];
|
|
}
|
|
else
|
|
{
|
|
_inputFieldOnelineLabel.attributedText = [self oneLinedCaptionForText:caption entities:entities];
|
|
_inputFieldOnelineLabel.hidden = (caption.length == 0);
|
|
_placeholderLabel.hidden = !_inputFieldOnelineLabel.hidden;
|
|
_fieldBackground.alpha = _placeholderLabel.hidden ? 1.0f : 0.0f;
|
|
}
|
|
|
|
[self.inputField setAttributedText:[TGMediaPickerCaptionInputPanel attributedStringForText:_caption entities:_entities fontSize:17.0f] keepFormatting:true animated:false];
|
|
}
|
|
|
|
+ (NSAttributedString *)attributedStringForText:(NSString *)text entities:(NSArray *)entities fontSize:(CGFloat)fontSize {
|
|
if (text == nil) {
|
|
return nil;
|
|
}
|
|
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: TGSystemFontOfSize(fontSize)}];
|
|
for (id entity in entities) {
|
|
if ([entity isKindOfClass:[TGMessageEntityMentionName class]]) {
|
|
TGMessageEntityMentionName *mentionEntity = entity;
|
|
static int64_t nextId = 1000000;
|
|
int64_t uniqueId = nextId;
|
|
nextId++;
|
|
@try {
|
|
[attributedString addAttributes:@{TGMentionUidAttributeName: [[TGInputTextTag alloc] initWithUniqueId:uniqueId left:true attachment:@(mentionEntity.userId)]} range:mentionEntity.range];
|
|
} @catch(NSException *e) {
|
|
}
|
|
}
|
|
else if (iosMajorVersion() >= 7) {
|
|
if ([entity isKindOfClass:[TGMessageEntityBold class]]) {
|
|
TGMessageEntityBold *boldEntity = entity;
|
|
@try {
|
|
[attributedString addAttributes:@{NSFontAttributeName: TGBoldSystemFontOfSize(fontSize)} range:boldEntity.range];
|
|
} @catch(NSException *e) {
|
|
}
|
|
} else if ([entity isKindOfClass:[TGMessageEntityItalic class]]) {
|
|
TGMessageEntityItalic *italicEntity = entity;
|
|
@try {
|
|
[attributedString addAttributes:@{NSFontAttributeName: TGItalicSystemFontOfSize(fontSize)} range:italicEntity.range];
|
|
} @catch(NSException *e) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return attributedString;
|
|
}
|
|
|
|
- (void)updateCounterWithText:(NSString *)text
|
|
{
|
|
bool appearance = false;
|
|
|
|
NSInteger textLength = text.length;
|
|
_counterLabel.text = [NSString stringWithFormat:@"%d", (int)(TGMediaPickerCaptionInputPanelCaptionLimit - textLength)];
|
|
|
|
bool hidden = (text.length < (TGMediaPickerCaptionInputPanelCaptionLimit - 100));
|
|
if (hidden != _counterLabel.hidden)
|
|
{
|
|
appearance = true;
|
|
|
|
[UIView transitionWithView:_counterLabel duration:0.16f options:UIViewAnimationOptionTransitionCrossDissolve animations:^
|
|
{
|
|
_counterLabel.hidden = hidden;
|
|
} completion:nil];
|
|
}
|
|
|
|
bool highlighted = (textLength > TGMediaPickerCaptionInputPanelCaptionLimit);
|
|
if (highlighted != _counterLabel.highlighted)
|
|
{
|
|
if (!appearance)
|
|
{
|
|
[UIView transitionWithView:_counterLabel duration:0.16f options:UIViewAnimationOptionTransitionCrossDissolve animations:^
|
|
{
|
|
_counterLabel.highlighted = highlighted;
|
|
} completion:nil];
|
|
}
|
|
else
|
|
{
|
|
_counterLabel.highlighted = highlighted;
|
|
}
|
|
}
|
|
|
|
_counterLabel.hidden = ![self isFirstResponder] || textLength < (TGMediaPickerCaptionInputPanelCaptionLimit - 100);
|
|
}
|
|
|
|
- (void)shakeControls
|
|
{
|
|
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
|
|
NSMutableArray *values = [[NSMutableArray alloc] init];
|
|
for (NSUInteger i = 0; i < 6; i++)
|
|
[values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(i % 2 == 0 ? -3.0f : 3.0f, 0.0f, 0.0f)]];
|
|
[values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0.0f, 0.0f, 0.0f)]];
|
|
animation.values = values;
|
|
NSMutableArray *keyTimes = [[NSMutableArray alloc] init];
|
|
for (NSUInteger i = 0; i < animation.values.count; i++)
|
|
[keyTimes addObject:@((NSTimeInterval)i / (animation.values.count - 1.0))];
|
|
animation.keyTimes = keyTimes;
|
|
animation.duration = 0.3;
|
|
[_wrapperView.layer addAnimation:animation forKey:@"transform"];
|
|
|
|
_dismissDisabled = true;
|
|
TGDispatchAfter(0.3, dispatch_get_main_queue(), ^
|
|
{
|
|
_dismissDisabled = false;
|
|
});
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (BOOL)becomeFirstResponder
|
|
{
|
|
[self handleFieldBackgroundTap:nil];
|
|
return true;
|
|
}
|
|
|
|
- (BOOL)isFirstResponder
|
|
{
|
|
return _inputField.internalTextView.isFirstResponder && !_dismissing;
|
|
}
|
|
|
|
- (void)growingTextViewDidBeginEditing:(HPGrowingTextView *)__unused growingTextView
|
|
{
|
|
id<TGMediaPickerCaptionInputPanelDelegate> delegate = self.delegate;
|
|
if ([delegate respondsToSelector:@selector(inputPanelFocused:)])
|
|
[delegate inputPanelFocused:self];
|
|
|
|
[self updateCounterWithText:_caption];
|
|
|
|
_inputField.alpha = 0.0f;
|
|
_doneButtonWrapper.userInteractionEnabled = true;
|
|
[UIView animateWithDuration:0.2f animations:^
|
|
{
|
|
_inputField.alpha = 1.0f;
|
|
_inputFieldOnelineLabel.alpha = 0.0f;
|
|
_fieldBackground.alpha = 1.0f;
|
|
_doneButtonWrapper.alpha = 1.0;
|
|
} completion:^(BOOL finished)
|
|
{
|
|
if (finished)
|
|
{
|
|
_inputFieldOnelineLabel.alpha = 1.0f;
|
|
_inputFieldOnelineLabel.hidden = true;
|
|
}
|
|
}];
|
|
|
|
if (_keyboardHeight < FLT_EPSILON)
|
|
{
|
|
[self adjustForOrientation:UIInterfaceOrientationPortrait keyboardHeight:0 duration:0.2f animationCurve:[TGViewController preferredAnimationCurve]];
|
|
}
|
|
|
|
[_inputField refreshHeight:false];
|
|
}
|
|
|
|
- (void)growingTextViewDidEndEditing:(HPGrowingTextView *)__unused growingTextView
|
|
{
|
|
_caption = _inputField.text;
|
|
|
|
__autoreleasing NSArray *entities = nil;
|
|
[_inputField textWithEntities:&entities];
|
|
_entities = entities;
|
|
|
|
_inputFieldOnelineLabel.attributedText = [self oneLinedCaptionForText:_caption entities:_entities];
|
|
_inputFieldOnelineLabel.alpha = 0.0f;
|
|
_inputFieldOnelineLabel.hidden = false;
|
|
|
|
[self updateCounterWithText:_caption];
|
|
|
|
_doneButtonWrapper.userInteractionEnabled = false;
|
|
[UIView animateWithDuration:0.2f animations:^
|
|
{
|
|
_inputField.alpha = 0.0f;
|
|
_inputFieldOnelineLabel.alpha = 1.0f;
|
|
_doneButtonWrapper.alpha = 0.0;
|
|
|
|
if (_caption.length == 0)
|
|
_fieldBackground.alpha = 0.0f;
|
|
} completion:^(BOOL finished)
|
|
{
|
|
if (finished)
|
|
{
|
|
_inputField.alpha = 1.0f;
|
|
_inputFieldClippingContainer.hidden = true;
|
|
}
|
|
}];
|
|
|
|
[self setAssociatedPanel:nil animated:true];
|
|
|
|
[self setButtonPressed];
|
|
}
|
|
|
|
- (void)growingTextView:(HPGrowingTextView *)__unused growingTextView willChangeHeight:(CGFloat)height duration:(NSTimeInterval)duration animationCurve:(int)animationCurve
|
|
{
|
|
UIEdgeInsets inputFieldInsets = [self _inputFieldInsets];
|
|
CGFloat inputContainerHeight = MAX([self baseHeight], height - 8 + inputFieldInsets.top + inputFieldInsets.bottom);
|
|
|
|
id<TGMediaPickerCaptionInputPanelDelegate> delegate = (id<TGMediaPickerCaptionInputPanelDelegate>)self.delegate;
|
|
if ([delegate respondsToSelector:@selector(inputPanelWillChangeHeight:height:duration:animationCurve:)])
|
|
{
|
|
[delegate inputPanelWillChangeHeight:self height:inputContainerHeight duration:duration animationCurve:animationCurve];
|
|
}
|
|
}
|
|
|
|
- (void)growingTextViewDidChange:(HPGrowingTextView *)__unused growingTextView afterSetText:(bool)__unused afterSetText afterPastingText:(bool)__unused afterPastingText
|
|
{
|
|
id<TGMediaPickerCaptionInputPanelDelegate> delegate = (id<TGMediaPickerCaptionInputPanelDelegate>)self.delegate;
|
|
|
|
int textLength = (int)growingTextView.text.length;
|
|
NSString *text = growingTextView.text;
|
|
|
|
UITextRange *selRange = _inputField.internalTextView.selectedTextRange;
|
|
UITextPosition *selStartPos = selRange.start;
|
|
NSInteger idx = [_inputField.internalTextView offsetFromPosition:_inputField.internalTextView.beginningOfDocument toPosition:selStartPos];
|
|
idx--;
|
|
|
|
NSString *candidateMention = nil;
|
|
bool candidateMentionStartOfLine = false;
|
|
NSString *candidateHashtag = nil;
|
|
NSString *candidateAlphacode = nil;
|
|
|
|
if (idx >= 0 && idx < textLength)
|
|
{
|
|
for (NSInteger i = idx; i >= 0; i--)
|
|
{
|
|
unichar c = [text characterAtIndex:i];
|
|
if (c == '@')
|
|
{
|
|
if (i == idx){
|
|
candidateMention = @"";
|
|
candidateMentionStartOfLine = i == 0;
|
|
}
|
|
else
|
|
{
|
|
@try {
|
|
candidateMention = [text substringWithRange:NSMakeRange(i + 1, idx - i)];
|
|
candidateMentionStartOfLine = i == 0;
|
|
} @catch(NSException *e) { }
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'))
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (candidateMention == nil)
|
|
{
|
|
static NSCharacterSet *characterSet = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
characterSet = [NSCharacterSet alphanumericCharacterSet];
|
|
});
|
|
|
|
if (idx >= 0 && idx < textLength)
|
|
{
|
|
for (NSInteger i = idx; i >= 0; i--)
|
|
{
|
|
unichar c = [text characterAtIndex:i];
|
|
if (c == '#')
|
|
{
|
|
if (i == idx)
|
|
candidateHashtag = @"";
|
|
else
|
|
{
|
|
@try {
|
|
candidateHashtag = [text substringWithRange:NSMakeRange(i + 1, idx - i)];
|
|
} @catch(NSException *e) { }
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if (c == ' ' || (![characterSet characterIsMember:c] && c != '_'))
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (candidateHashtag == nil)
|
|
{
|
|
if (idx >= 0 && idx < textLength)
|
|
{
|
|
for (NSInteger i = idx; i >= 0; i--)
|
|
{
|
|
unichar c = [text characterAtIndex:i];
|
|
unichar previousC = 0;
|
|
if (i > 0)
|
|
previousC = [text characterAtIndex:i - 1];
|
|
if (c == ':' && (previousC == 0 || ![characterSet characterIsMember:previousC]))
|
|
{
|
|
if (i == idx) {
|
|
candidateAlphacode = nil;
|
|
}
|
|
else
|
|
{
|
|
@try {
|
|
candidateAlphacode = [text substringWithRange:NSMakeRange(i + 1, idx - i)];
|
|
} @catch(NSException *e) { }
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (c == ' ' || (![characterSet characterIsMember:c]))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ([delegate respondsToSelector:@selector(inputPanelMentionEntered:mention:startOfLine:)])
|
|
[delegate inputPanelMentionEntered:self mention:candidateMention startOfLine:candidateMentionStartOfLine];
|
|
|
|
if ([delegate respondsToSelector:@selector(inputPanelHashtagEntered:hashtag:)])
|
|
[delegate inputPanelHashtagEntered:self hashtag:candidateHashtag];
|
|
|
|
if ([delegate respondsToSelector:@selector(inputPanelAlphacodeEntered:alphacode:)])
|
|
[delegate inputPanelAlphacodeEntered:self alphacode:candidateAlphacode];
|
|
|
|
if ([delegate respondsToSelector:@selector(inputPanelTextChanged:text:)])
|
|
[delegate inputPanelTextChanged:self text:text];
|
|
|
|
[self updateCounterWithText:text];
|
|
}
|
|
|
|
- (void)addNewLine
|
|
{
|
|
self.caption = [NSString stringWithFormat:@"%@\n", self.caption];
|
|
}
|
|
|
|
- (NSMutableAttributedString *)oneLinedCaptionForText:(NSString *)text entities:(NSArray *)entities
|
|
{
|
|
static NSString *tokenString = nil;
|
|
if (tokenString == nil)
|
|
{
|
|
unichar tokenChar = 0x2026;
|
|
tokenString = [[NSString alloc] initWithCharacters:&tokenChar length:1];
|
|
}
|
|
|
|
if (text == nil)
|
|
return nil;
|
|
|
|
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithAttributedString:[TGMediaPickerCaptionInputPanel attributedStringForText:text entities:entities fontSize:17.0f]];
|
|
|
|
for (NSUInteger i = 0; i < string.length; i++)
|
|
{
|
|
unichar c = [text characterAtIndex:i];
|
|
if (c == '\t' || c == '\n')
|
|
{
|
|
[string insertAttributedString:[[NSAttributedString alloc] initWithString:tokenString attributes:@{NSFontAttributeName:TGSystemFontOfSize(17.0f)}] atIndex:i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return string;
|
|
}
|
|
|
|
- (NSInteger)textCaretPosition {
|
|
UITextRange *selRange = _inputField.internalTextView.selectedTextRange;
|
|
UITextPosition *selStartPos = selRange.start;
|
|
NSInteger idx = [_inputField.internalTextView offsetFromPosition:_inputField.internalTextView.beginningOfDocument toPosition:selStartPos];
|
|
return idx;
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (void)replaceMention:(NSString *)mention
|
|
{
|
|
[HPGrowingTextView replaceMention:mention inputField:_inputField username:true userId:0];
|
|
}
|
|
|
|
- (void)replaceMention:(NSString *)mention username:(bool)username userId:(int32_t)userId {
|
|
[HPGrowingTextView replaceMention:mention inputField:_inputField username:username userId:userId];
|
|
}
|
|
|
|
- (void)replaceHashtag:(NSString *)hashtag
|
|
{
|
|
[HPGrowingTextView replaceHashtag:hashtag inputField:_inputField];
|
|
}
|
|
|
|
- (bool)shouldDisplayPanels
|
|
{
|
|
return true;
|
|
}
|
|
|
|
- (TGModernConversationAssociatedInputPanel *)associatedPanel
|
|
{
|
|
return _associatedPanel;
|
|
}
|
|
|
|
- (void)setAssociatedPanel:(TGModernConversationAssociatedInputPanel *)associatedPanel animated:(bool)animated
|
|
{
|
|
if (_associatedPanel != associatedPanel)
|
|
{
|
|
TGModernConversationAssociatedInputPanel *currentPanel = _associatedPanel;
|
|
if (currentPanel != nil)
|
|
{
|
|
if (animated)
|
|
{
|
|
[UIView animateWithDuration:0.18 animations:^
|
|
{
|
|
currentPanel.alpha = 0.0f;
|
|
} completion:^(BOOL finished)
|
|
{
|
|
if (finished)
|
|
[currentPanel removeFromSuperview];
|
|
}];
|
|
}
|
|
else
|
|
[currentPanel removeFromSuperview];
|
|
}
|
|
|
|
_associatedPanel = associatedPanel;
|
|
if (_associatedPanel != nil)
|
|
{
|
|
if ([_associatedPanel fillsAvailableSpace]) {
|
|
CGFloat inputContainerHeight = [self heightForInputFieldHeight:[self isFirstResponder] ? _inputField.frame.size.height : 0];
|
|
_associatedPanel.frame = CGRectMake(0.0f, -_contentAreaHeight + inputContainerHeight, self.frame.size.width, _contentAreaHeight - inputContainerHeight);
|
|
} else {
|
|
__weak TGMediaPickerCaptionInputPanel *weakSelf = self;
|
|
_associatedPanel.preferredHeightUpdated = ^
|
|
{
|
|
__strong TGMediaPickerCaptionInputPanel *strongSelf = weakSelf;
|
|
if (strongSelf != nil)
|
|
{
|
|
strongSelf->_associatedPanel.frame = CGRectMake(0.0f, -[strongSelf->_associatedPanel preferredHeight], strongSelf.frame.size.width, [strongSelf shouldDisplayPanels] ? [strongSelf->_associatedPanel preferredHeight] : 0.0f);
|
|
}
|
|
};
|
|
_associatedPanel.frame = CGRectMake(0.0f, -[_associatedPanel preferredHeight], self.frame.size.width, [self shouldDisplayPanels] ? [_associatedPanel preferredHeight] : 0.0f);
|
|
}
|
|
|
|
[self addSubview:_associatedPanel];
|
|
if (animated)
|
|
{
|
|
_associatedPanel.alpha = 0.0f;
|
|
[UIView animateWithDuration:0.18 animations:^
|
|
{
|
|
_associatedPanel.alpha = 1.0f;
|
|
}];
|
|
}
|
|
else
|
|
{
|
|
_associatedPanel.alpha = 1.0f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)setContentAreaHeight:(CGFloat)contentAreaHeight
|
|
{
|
|
_contentAreaHeight = contentAreaHeight;
|
|
[self setNeedsLayout];
|
|
|
|
_dismissing = false;
|
|
}
|
|
|
|
#pragma mark - Style
|
|
|
|
- (UIEdgeInsets)_inputFieldInsets
|
|
{
|
|
static UIEdgeInsets insets;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
|
|
insets = UIEdgeInsetsMake(6.0f, 6.0f, 6.0f, 6.0f);
|
|
else
|
|
insets = UIEdgeInsetsMake(11.0f, 11.0f, 11.0f, 11.0f);
|
|
});
|
|
|
|
return insets;
|
|
}
|
|
|
|
- (UIEdgeInsets)_inputFieldInternalEdgeInsets
|
|
{
|
|
static UIEdgeInsets insets;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
if (!TGIsPad())
|
|
insets = UIEdgeInsetsMake(-3.0f, 8.0f, 0.0f, 0.0f);
|
|
else
|
|
insets = UIEdgeInsetsMake(-2.0f, 8.0f, 0.0f, 0.0f);
|
|
});
|
|
|
|
return insets;
|
|
}
|
|
|
|
- (CGPoint)_inputFieldPlaceholderOffset
|
|
{
|
|
static CGPoint offset;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
if (!TGIsPad())
|
|
offset = CGPointMake(12.0f, 5.0f + TGScreenPixel);
|
|
else
|
|
offset = CGPointMake(12.0f, 6.0f);
|
|
});
|
|
|
|
return offset;
|
|
}
|
|
|
|
- (CGFloat)heightForInputFieldHeight:(CGFloat)inputFieldHeight
|
|
{
|
|
if (inputFieldHeight < FLT_EPSILON)
|
|
inputFieldHeight = 36;
|
|
|
|
if (TGIsPad())
|
|
inputFieldHeight += 4;
|
|
|
|
UIEdgeInsets inputFieldInsets = [self _inputFieldInsets];
|
|
CGFloat height = MAX([self baseHeight], inputFieldHeight - 4 + inputFieldInsets.top + inputFieldInsets.bottom);
|
|
|
|
return height;
|
|
}
|
|
|
|
- (CGFloat)baseHeight
|
|
{
|
|
static CGFloat value = 0.0f;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
value = !TGIsPad() ? 45.0f : 56.0f;
|
|
});
|
|
|
|
return value;
|
|
}
|
|
|
|
- (CGPoint)_setButtonOffset
|
|
{
|
|
static CGPoint offset;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
|
|
offset = CGPointZero;
|
|
else
|
|
offset = CGPointMake(-11.0f, -6.0f);
|
|
});
|
|
|
|
return offset;
|
|
}
|
|
|
|
- (int)_maxNumberOfLinesForSize:(CGSize)size
|
|
{
|
|
if (size.height <= 320.0f - FLT_EPSILON) {
|
|
return 3;
|
|
} else if (size.height <= 480.0f - FLT_EPSILON) {
|
|
return 5;
|
|
} else {
|
|
return 7;
|
|
}
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
|
{
|
|
if (_associatedPanel != nil)
|
|
{
|
|
UIView *result = [_associatedPanel hitTest:[self convertPoint:point toView:_associatedPanel] withEvent:event];
|
|
if (result != nil)
|
|
return result;
|
|
}
|
|
|
|
return [super hitTest:point withEvent:event];
|
|
}
|
|
|
|
- (void)layoutSubviews
|
|
{
|
|
[super layoutSubviews];
|
|
|
|
CGRect frame = self.frame;
|
|
|
|
if (_associatedPanel != nil)
|
|
{
|
|
CGFloat inputContainerHeight = [self heightForInputFieldHeight:[self isFirstResponder] ? _inputField.frame.size.height : 0];
|
|
|
|
CGRect associatedPanelFrame = CGRectZero;
|
|
if ([_associatedPanel fillsAvailableSpace]) {
|
|
associatedPanelFrame = CGRectMake(0.0f, -_contentAreaHeight + inputContainerHeight, self.frame.size.width, _contentAreaHeight - inputContainerHeight);
|
|
} else {
|
|
associatedPanelFrame = CGRectMake(0.0f, -[_associatedPanel preferredHeight], frame.size.width, [self shouldDisplayPanels] ? [_associatedPanel preferredHeight] : 0.0f);
|
|
}
|
|
|
|
if (!CGRectEqualToRect(associatedPanelFrame, _associatedPanel.frame))
|
|
_associatedPanel.frame = associatedPanelFrame;
|
|
}
|
|
|
|
UIEdgeInsets inputFieldInsets = [self _inputFieldInsets];
|
|
if (self.isFirstResponder) {
|
|
inputFieldInsets.right += 41.0;
|
|
}
|
|
|
|
CGFloat inputContainerHeight = [self heightForInputFieldHeight:self.isFirstResponder ? _inputField.frame.size.height : 0];
|
|
setViewFrame(_fieldBackground, CGRectMake(inputFieldInsets.left, inputFieldInsets.top, frame.size.width - inputFieldInsets.left - inputFieldInsets.right, inputContainerHeight - inputFieldInsets.top - inputFieldInsets.bottom));
|
|
|
|
UIEdgeInsets inputFieldInternalEdgeInsets = [self _inputFieldInternalEdgeInsets];
|
|
CGRect onelineFrame = _fieldBackground.frame;
|
|
onelineFrame.origin.x += inputFieldInternalEdgeInsets.left + 5;
|
|
onelineFrame.origin.y += inputFieldInternalEdgeInsets.top + TGScreenPixel;
|
|
onelineFrame.size.width -= inputFieldInternalEdgeInsets.left * 2 + 10;
|
|
onelineFrame.size.height = 36;
|
|
setViewFrame(_inputFieldOnelineLabel, onelineFrame);
|
|
|
|
CGRect placeholderFrame = CGRectMake(floor((self.frame.size.width - _placeholderLabel.frame.size.width) / 2.0f), floor(([self baseHeight] - _placeholderLabel.frame.size.height) / 2.0f), _placeholderLabel.frame.size.width, _placeholderLabel.frame.size.height);
|
|
if (self.isFirstResponder)
|
|
placeholderFrame.origin.x = onelineFrame.origin.x;
|
|
setViewFrame(_placeholderLabel, placeholderFrame);
|
|
|
|
CGRect inputFieldClippingFrame = _fieldBackground.frame;
|
|
setViewFrame(_inputFieldClippingContainer, inputFieldClippingFrame);
|
|
|
|
CGFloat inputFieldWidth = _inputFieldClippingContainer.frame.size.width - inputFieldInternalEdgeInsets.left - 36;
|
|
if (fabs(inputFieldWidth - _inputField.frame.size.width) > FLT_EPSILON)
|
|
{
|
|
CGRect inputFieldFrame = CGRectMake(inputFieldInternalEdgeInsets.left, inputFieldInternalEdgeInsets.top + TGRetinaPixel, inputFieldWidth, _inputFieldClippingContainer.frame.size.height);
|
|
setViewFrame(_inputField, inputFieldFrame);
|
|
}
|
|
|
|
_doneButtonWrapper.frame = CGRectMake(self.frame.size.width - 47.0, CGRectGetMaxY(_fieldBackground.frame) - _doneButton.frame.size.height + 8.0, _doneButton.frame.size.width, _doneButton.frame.size.height);
|
|
}
|
|
|
|
@end
|