YYTextEditExample.m 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //
  2. // YYTextEditExample.m
  3. // YYKitExample
  4. //
  5. // Created by ibireme on 15/9/3.
  6. // Copyright (c) 2015 ibireme. All rights reserved.
  7. //
  8. #import "YYTextEditExample.h"
  9. #import "YYText.h"
  10. #import "YYImage.h"
  11. #import "UIImage+YYWebImage.h"
  12. #import "UIView+YYAdd.h"
  13. #import "NSBundle+YYAdd.h"
  14. #import "NSString+YYAdd.h"
  15. #import "UIControl+YYAdd.h"
  16. #import "CALayer+YYAdd.h"
  17. #import "NSData+YYAdd.h"
  18. #import "UIGestureRecognizer+YYAdd.h"
  19. #import "YYTextExampleHelper.h"
  20. @interface YYTextEditExample () <YYTextViewDelegate, YYTextKeyboardObserver>
  21. @property (nonatomic, assign) YYTextView *textView;
  22. @property (nonatomic, strong) UIImageView *imageView;
  23. @property (nonatomic, strong) UISwitch *verticalSwitch;
  24. @property (nonatomic, strong) UISwitch *debugSwitch;
  25. @property (nonatomic, strong) UISwitch *exclusionSwitch;
  26. @end
  27. @implementation YYTextEditExample
  28. - (void)viewDidLoad {
  29. [super viewDidLoad];
  30. self.view.backgroundColor = [UIColor whiteColor];
  31. if ([self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)]) {
  32. self.automaticallyAdjustsScrollViewInsets = NO;
  33. }
  34. [self initImageView];
  35. __weak typeof(self) _self = self;
  36. UIView *toolbar;
  37. if ([UIVisualEffectView class]) {
  38. toolbar = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]];
  39. } else {
  40. toolbar = [UIToolbar new];
  41. }
  42. toolbar.size = CGSizeMake(kScreenWidth, 40);
  43. toolbar.top = kiOS7Later ? 64 : 0;
  44. [self.view addSubview:toolbar];
  45. NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@"It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the season of light, it was the season of darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us. We were all going direct to heaven, we were all going direct the other way.\n\n这是最好的时代,这是最坏的时代;这是智慧的时代,这是愚蠢的时代;这是信仰的时期,这是怀疑的时期;这是光明的季节,这是黑暗的季节;这是希望之春,这是失望之冬;人们面前有着各样事物,人们面前一无所有;人们正在直登天堂,人们正在直下地狱。"];
  46. text.yy_font = [UIFont fontWithName:@"Times New Roman" size:20];
  47. text.yy_lineSpacing = 4;
  48. text.yy_firstLineHeadIndent = 20;
  49. YYTextView *textView = [YYTextView new];
  50. textView.attributedText = text;
  51. textView.size = self.view.size;
  52. textView.textContainerInset = UIEdgeInsetsMake(10, 10, 10, 10);
  53. textView.delegate = self;
  54. if (kiOS7Later) {
  55. textView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
  56. } else {
  57. textView.height -= 64;
  58. }
  59. textView.contentInset = UIEdgeInsetsMake(toolbar.bottom, 0, 0, 0);
  60. textView.scrollIndicatorInsets = textView.contentInset;
  61. textView.selectedRange = NSMakeRange(text.length, 0);
  62. [self.view insertSubview:textView belowSubview:toolbar];
  63. self.textView = textView;
  64. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  65. [textView becomeFirstResponder];
  66. });
  67. /*------------------------------ Toolbar ---------------------------------*/
  68. UILabel *label;
  69. label = [UILabel new];
  70. label.backgroundColor = [UIColor clearColor];
  71. label.font = [UIFont systemFontOfSize:14];
  72. label.text = @"Vertical:";
  73. label.size = CGSizeMake([label.text widthForFont:label.font] + 2, toolbar.height);
  74. label.left = 10;
  75. [toolbar addSubview:label];
  76. _verticalSwitch = [UISwitch new];
  77. [_verticalSwitch sizeToFit];
  78. _verticalSwitch.centerY = toolbar.height / 2;
  79. _verticalSwitch.left = label.right - 5;
  80. _verticalSwitch.layer.transformScale = 0.8;
  81. [_verticalSwitch addBlockForControlEvents:UIControlEventValueChanged block:^(UISwitch *switcher) {
  82. [_self.textView endEditing:YES];
  83. if (switcher.isOn) {
  84. [_self setExclusionPathEnabled:NO];
  85. _self.exclusionSwitch.on = NO;
  86. }
  87. _self.exclusionSwitch.enabled = !switcher.isOn;
  88. _self.textView.verticalForm = switcher.isOn; /// Set vertical form
  89. }];
  90. [toolbar addSubview:_verticalSwitch];
  91. label = [UILabel new];
  92. label.backgroundColor = [UIColor clearColor];
  93. label.font = [UIFont systemFontOfSize:14];
  94. label.text = @"Debug:";
  95. label.size = CGSizeMake([label.text widthForFont:label.font] + 2, toolbar.height);
  96. label.left = _verticalSwitch.right + 5;
  97. [toolbar addSubview:label];
  98. _debugSwitch = [UISwitch new];
  99. [_debugSwitch sizeToFit];
  100. _debugSwitch.on = [YYTextExampleHelper isDebug];
  101. _debugSwitch.centerY = toolbar.height / 2;
  102. _debugSwitch.left = label.right - 5;
  103. _debugSwitch.layer.transformScale = 0.8;
  104. [_debugSwitch addBlockForControlEvents:UIControlEventValueChanged block:^(UISwitch *switcher) {
  105. [YYTextExampleHelper setDebug:switcher.isOn];
  106. }];
  107. [toolbar addSubview:_debugSwitch];
  108. label = [UILabel new];
  109. label.backgroundColor = [UIColor clearColor];
  110. label.font = [UIFont systemFontOfSize:14];
  111. label.text = @"Exclusion:";
  112. label.size = CGSizeMake([label.text widthForFont:label.font] + 2, toolbar.height);
  113. label.left = _debugSwitch.right + 5;
  114. [toolbar addSubview:label];
  115. _exclusionSwitch = [UISwitch new];
  116. [_exclusionSwitch sizeToFit];
  117. _exclusionSwitch.centerY = toolbar.height / 2;
  118. _exclusionSwitch.left = label.right - 5;
  119. _exclusionSwitch.layer.transformScale = 0.8;
  120. [_exclusionSwitch addBlockForControlEvents:UIControlEventValueChanged block:^(UISwitch *switcher) {
  121. [_self setExclusionPathEnabled:switcher.isOn];
  122. }];
  123. [toolbar addSubview:_exclusionSwitch];
  124. [[YYTextKeyboardManager defaultManager] addObserver:self];
  125. }
  126. - (void)dealloc {
  127. [[YYTextKeyboardManager defaultManager] removeObserver:self];
  128. }
  129. - (void)setExclusionPathEnabled:(BOOL)enabled {
  130. if (enabled) {
  131. [self.textView addSubview:self.imageView];
  132. UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.imageView.frame
  133. cornerRadius:self.imageView.layer.cornerRadius];
  134. self.textView.exclusionPaths = @[path]; /// Set exclusion paths
  135. } else {
  136. [self.imageView removeFromSuperview];
  137. self.textView.exclusionPaths = nil;
  138. }
  139. }
  140. - (void)initImageView {
  141. NSData *data = [NSData dataNamed:@"dribbble256_imageio.png"];
  142. UIImage *image = [[YYImage alloc] initWithData:data scale:2];
  143. UIImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:image];
  144. imageView.clipsToBounds = YES;
  145. imageView.userInteractionEnabled = YES;
  146. imageView.layer.cornerRadius = imageView.height / 2;
  147. imageView.center = CGPointMake(kScreenWidth / 2, kScreenWidth / 2);
  148. self.imageView = imageView;
  149. __weak typeof(self) _self = self;
  150. UIPanGestureRecognizer *g = [[UIPanGestureRecognizer alloc] initWithActionBlock:^(UIPanGestureRecognizer *g) {
  151. __strong typeof(_self) self = _self;
  152. if (!self) return;
  153. CGPoint p = [g locationInView:self.textView];
  154. self.imageView.center = p;
  155. UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.imageView.frame
  156. cornerRadius:self.imageView.layer.cornerRadius];
  157. self.textView.exclusionPaths = @[path];
  158. }];
  159. [imageView addGestureRecognizer:g];
  160. }
  161. - (void)edit:(UIBarButtonItem *)item {
  162. if (_textView.isFirstResponder) {
  163. [_textView resignFirstResponder];
  164. } else {
  165. [_textView becomeFirstResponder];
  166. }
  167. }
  168. #pragma mark text view
  169. - (void)textViewDidBeginEditing:(YYTextView *)textView {
  170. UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
  171. target:self
  172. action:@selector(edit:)];
  173. self.navigationItem.rightBarButtonItem = buttonItem;
  174. }
  175. - (void)textViewDidEndEditing:(YYTextView *)textView {
  176. self.navigationItem.rightBarButtonItem = nil;
  177. }
  178. #pragma mark - keyboard
  179. - (void)keyboardChangedWithTransition:(YYTextKeyboardTransition)transition {
  180. BOOL clipped = NO;
  181. if (_textView.isVerticalForm && transition.toVisible) {
  182. CGRect rect = [[YYTextKeyboardManager defaultManager] convertRect:transition.toFrame toView:self.view];
  183. if (CGRectGetMaxY(rect) == self.view.height) {
  184. CGRect textFrame = self.view.bounds;
  185. textFrame.size.height -= rect.size.height;
  186. _textView.frame = textFrame;
  187. clipped = YES;
  188. }
  189. }
  190. if (!clipped) {
  191. _textView.frame = self.view.bounds;
  192. }
  193. }
  194. @end