// // CustomTextView.m // JasonDevelop // // Created by Jason Lee on 10/26/14. // Copyright (c) jasondevelop. All rights reserved. // #import "NSString-Addtions.h" #import "CommonUtil.h" #import "CustomTextView.h" #import "ImageUtil.h" #define kUIBtnTintColor [UIColor whiteColor] #define kfBoxCap 4.0f #define kUIPlaceHolderColor RGBCOLOR(170, 170, 170) @interface CustomTextView () { @protected UIView *_targetSuperView; CGRect _cRect; CGRect _superRect; CGPoint _contentOffset; CGFloat _marginTop, _naviMargin, _adjustY; UIBarButtonItem *_btnPrev, *_btnNext, *_btnClose; UIToolbar *_toolBar; NSMutableArray *_barItems; UIBarButtonItem *_btnFlexibleSpace; UIEdgeInsets _bgInsets; BOOL _isSecureEntry; UIImage *_bgImage; BOOL _isScrollUp; UIColor *_normalTextColor; } @end @implementation CustomTextView @dynamic delegate; - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { _customTextViewSuperview = CustomTextViewSuperviewIsViewController; self.inputAccessoryView = [self generateAccessoryView]; _bgImageName = @"img_input_line_bg_default"; UIImage *bgImage = [UIImage imageNamed:_bgImageName]; if (bgImage) { _bgInsets = UIEdgeInsetsMake(kfBoxCap, kfBoxCap, kfBoxCap, kfBoxCap); bgImage = [ImageUtil resizableImageWithCapInsets:_bgInsets resizingMode:UIImageResizingModeStretch img:bgImage]; // [self setBackground:bgImage]; } _cRect = self.frame; } return self; } - (void)awakeFromNib { self.customTextViewSuperview = CustomTextViewSuperviewIsViewController; self.inputAccessoryView = [self generateAccessoryView]; _bgImageName = _bgImageName && ![_bgImageName isEmptyString] ? _bgImageName : @"img_input_line_bg_default"; _bgImage = [UIImage imageNamed:_bgImageName]; if (_bgImage) { if (!CGRectEqualToRect(_rectForCapBackground, CGRectZero)) {//rectForCap이 설정된 경우, 이미지를 리사이즈함. CGFloat top, left, bottom, right; top = CGRectGetMinY(_rectForCapBackground); left = CGRectGetMinX(_rectForCapBackground); bottom = CGRectGetHeight(_rectForCapBackground); right = CGRectGetWidth(_rectForCapBackground); _bgInsets = UIEdgeInsetsMake(top, left, bottom, right); } else { _bgInsets = UIEdgeInsetsMake(kfBoxCap, kfBoxCap, kfBoxCap, kfBoxCap); } _bgImage = [ImageUtil resizableImageWithCapInsets:_bgInsets resizingMode:UIImageResizingModeStretch img:_bgImage]; } _cRect = self.frame; _normalTextColor = self.textColor; if (_placeHolder) { self.text = _placeHolder; } #ifdef DEBUG NSString *identifier = [NSString stringWithFormat:@"%@", self.placeHolder]; [self setValue:identifier forKey:@"layoutDebuggingIdentifier"]; #endif self.textContainerInset = UIEdgeInsetsMake(12, 12, 12, 12); } - (void)drawRect:(CGRect)rect { _bgImage = [ImageUtil resizableImageWithCapInsets:_bgInsets resizingMode:UIImageResizingModeStretch img:_bgImage]; [_bgImage drawInRect:rect]; self.textColor = [self.text isEqualToString:_placeHolder] ? self.placeHolderColor : _normalTextColor; } - (UIView *)generateAccessoryView { CGFloat width = [UIScreen mainScreen].bounds.size.width; _toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, 0.0, width, 44.0)]; _toolBar.barStyle = UIBarStyleBlack; _toolBar.translucent = YES; _barItems = [NSMutableArray new]; _btnFlexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; _btnPrev = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"이전", @"이전") style:UIBarButtonItemStylePlain target:self action:@selector(goPrevField:)]; _btnNext = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"다음", @"다음") style:UIBarButtonItemStylePlain target:self action:@selector(goNextField:)]; _btnClose = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"닫기", @"닫기") style:UIBarButtonItemStylePlain target:self action:@selector(hideKeyboard:)]; if (IOS_VERSION >= 7.0f) { _btnClose.tintColor = kUIBtnTintColor; _btnPrev.tintColor = kUIBtnTintColor; _btnNext.tintColor = kUIBtnTintColor; } [_barItems addObject:_btnFlexibleSpace]; [_barItems addObject:_btnClose]; [_toolBar setItems:_barItems animated:YES]; return _toolBar; } - (void)setCustomTextViewMove:(CustomTextViewMove)customTextViewMove { [_barItems removeAllObjects]; switch (customTextViewMove) { case CustomTextViewMovePrev: _btnNext.enabled = NO; [_barItems addObject:_btnPrev]; [_barItems addObject:_btnNext]; [_barItems addObject:_btnFlexibleSpace]; [_barItems addObject:_btnClose]; break; case CustomTextViewMoveNext: _btnPrev.enabled = NO; [_barItems addObject:_btnPrev]; [_barItems addObject:_btnNext]; [_barItems addObject:_btnFlexibleSpace]; [_barItems addObject:_btnClose]; break; case CustomTextVoewMoveBoth: [_barItems addObject:_btnPrev]; [_barItems addObject:_btnNext]; [_barItems addObject:_btnFlexibleSpace]; [_barItems addObject:_btnClose]; break; default: break; } [_toolBar setItems:_barItems animated:YES]; } - (void)setCustomTextViewSuperview:(CustomTextViewSuperview)customTextViewSuperview { if (!_autoScrollUp) { return; } _customTextViewSuperview = customTextViewSuperview; _naviMargin = 20.0f; if (_customTextViewSuperview == CustomTextViewSuperviewIsViewController) { UIViewController *vc = [CommonUtil currentViewController]; _targetSuperView = vc.view; } else if (_customTextViewSuperview == CustomTextViewSuperviewIsPopup) { _targetSuperView = self.superview.superview; } else if (_customTextViewSuperview == CustomTextViewSuperviewIsPopupContentView) { _targetSuperView = self.superview.superview.superview; } else if (_customTextViewSuperview == CustomTextViewSuperviewIsScrollView) { _targetSuperView = self.superview; if ([_targetSuperView isKindOfClass:[UIScrollView class]]) { UIScrollView *sv = (UIScrollView *)_targetSuperView; _contentOffset = sv.contentOffset; } }else if (_customTextViewSuperview == CustomTextViewSuperviewIsContentView) { _targetSuperView = self.superview.superview.superview; _naviMargin = 85.0f; } // if (_customTextViewSuperview == CustomTextViewSuperviewIsView) { // _targetSuperView = self.superview; // } else if (_customTextViewSuperview == CustomTextViewSuperviewIsViewController) { // UIViewController *vc = [AOTFacade facade].currentViewController; // _targetSuperView = vc.view; // } else if (_customTextViewSuperview == CustomTextViewSuperviewIsPopup) { // _targetSuperView = self.superview.superview; // } } - (void)scrollUp { if (_autoScrollUp) { if (CGRectEqualToRect(CGRectZero, gKeyboardRect)) { [self performSelector:@selector(scrollUp) withObject:nil afterDelay:0.1f]; return; } if (!_targetSuperView) { [self setCustomTextViewSuperview:_customTextViewSuperview]; } CGRect selfRect = self.frame; if (CGRectEqualToRect(_superRect, CGRectZero)) {//기존 위치를 저장함. _superRect = _targetSuperView.frame; } CGRect cr = [self.superview convertRect:selfRect toView:_targetSuperView]; if (_customTextViewSuperview == CustomTextViewSuperviewIsPopupContentView || _customTextViewSuperview == CustomTextViewSuperviewIsChildViewController) { cr = [self.superview convertRect:selfRect toView:[[UIApplication sharedApplication].delegate window]]; } CGFloat cy = CGRectGetMaxY(cr) + _adjustY; CGFloat ay = gKeyboardRect.size.height + 30;//(gKeyboardRect.size.height + KEYBOARD_ACCESSORY_HEIGHT + KEYBOARD_PREDICTS_HEIGHT); CGFloat ky = ([UIScreen mainScreen].bounds.size.height - _naviMargin) - ay; // 260 if (cy >= ky) { __block CGRect scrollRect = _targetSuperView.frame; scrollRect.origin.y = ky - cy; [UIView animateWithDuration:kfAnimationDur animations:^{ if ([_targetSuperView isKindOfClass:[UIScrollView class]]) { CGFloat offsetY = _contentOffset.y + (cy - ky); [(UIScrollView *)_targetSuperView setContentOffset:CGPointMake(0, offsetY) animated:NO]; } else { if (_customTextViewSuperview == CustomTextViewSuperviewIsPopupContentView || _customTextViewSuperview == CustomTextViewSuperviewIsChildViewController) { scrollRect.origin.y += _superRect.origin.y; } _targetSuperView.frame = scrollRect; } } completion:^(BOOL finished) { _isScrollUp = YES; }]; } else { if (!CGRectEqualToRect(_superRect, CGRectZero)) { [UIView animateWithDuration:kfAnimationDur animations:^{ _targetSuperView.frame = _superRect; } completion:^(BOOL finished) { _isScrollUp = YES; }]; } } } } - (BOOL)becomeFirstResponder { if ([_placeHolder isEqualToString:self.text]) { self.text = ksEmptyString; } //redraw background image _bgImage = _bgPressImageName && ![_bgPressImageName isEmptyString] ? [UIImage imageNamed:_bgPressImageName] : _bgImage; [self setNeedsDisplay]; if (_isScrollUp) { return [super becomeFirstResponder]; } _isScrollUp = NO; [self scrollUp]; return [super becomeFirstResponder]; } - (BOOL)resignFirstResponder { // NSLog(@"%@, resignFirstResponder", self); if ([self.text isEqualToString:ksEmptyString]) { self.text = _placeHolder; } //redraw background image _bgImage = _bgImageName && ![_bgImageName isEmptyString] ? [UIImage imageNamed:_bgImageName] : [UIImage imageNamed:@"input_wh"]; [self setNeedsDisplay]; if (_autoScrollUp) { // if (_customTextViewSuperview == CustomTextViewSuperviewIsViewController) { // UIViewController *vc = [CommonUtil currentViewController]; // _targetSuperView = vc.view; // } else if (_customTextViewSuperview == CustomTextViewSuperviewIsPopup) { // _targetSuperView = self.superview.superview; // } [UIView animateWithDuration:kfAnimationDur animations:^{ if ([_targetSuperView isKindOfClass:[UIScrollView class]]) { [(UIScrollView *)_targetSuperView setContentOffset:_contentOffset animated:NO]; } else if (!CGRectIsEmpty(_superRect)) { _targetSuperView.frame = _superRect; NSLog(@"_superRect2 %@", NSStringFromCGRect(_superRect)); } } completion:^(BOOL finished) { _isScrollUp = NO; }]; } return [super resignFirstResponder]; } - (void)goPrevField:(id)sender { [self resignFirstResponder]; if ([self.delegate respondsToSelector:@selector(moveToPrevField:)]) { [self.delegate moveToPrevField:self]; } } - (void)goNextField:(id)sender { [self resignFirstResponder]; if ([self.delegate respondsToSelector:@selector(moveToNextField:)]) { [self.delegate moveToNextField:self]; } } - (void)hideKeyboard:(id)sender { [self resignFirstResponder]; if ([self.delegate respondsToSelector:@selector(willHideKeyboard:)]) { [self.delegate willHideKeyboard:self]; } } //-(void)textViewDidChange:(UITextView *)textView { // // Enable and disable lblPlaceHolderText // if ([textView.text length] > 0) { // [textView setBackgroundColor:[UIColor whiteColor]]; //// [lblPlaceHolderText setHidden:YES]; // } else { // [textView setBackgroundColor:[UIColor clearColor]]; //// [lblPlaceHolderText setHidden:NO]; // } //} @end