TCVideoTextFiled.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. //
  2. // TCVideoTextFiled.m
  3. // DeviceManageIOSApp
  4. //
  5. // Created by rushanting on 2017/5/22.
  6. // Copyright © 2017年 tencent. All rights reserved.
  7. //
  8. #import "TCVideoTextFiled.h"
  9. //#import "UIView+AdditionsX12.h"
  10. #import "ColorMacro.h"
  11. #define kDefaultText @"点击修改文字"
  12. @interface TCVideoTextFiled () <UITextViewDelegate, UITextFieldDelegate>
  13. {
  14. UILabel* _textLabel;
  15. UIView* _borderView;
  16. UIButton* _deleteBtn;
  17. UIButton* _styleBtn;
  18. UIButton* _scaleRotateBtn;
  19. UITextView* _inputTextView;
  20. UIButton* _inputConfirmBtn;
  21. UITextField* _hiddenTextField;
  22. BOOL _isInputting;
  23. //己旋转角度
  24. CGFloat _rotateAngle;
  25. NSInteger _styleIndex;
  26. }
  27. @end
  28. @implementation TCVideoTextFiled
  29. - (id)initWithFrame:(CGRect)frame
  30. {
  31. if (self = [super initWithFrame:frame]) {
  32. _styleIndex = 0;
  33. _textLabel = [UILabel new];
  34. _textLabel.text = kDefaultText;
  35. _textLabel.textColor = UIColor.whiteColor;
  36. _textLabel.shadowOffset = CGSizeMake(2, 2);
  37. _textLabel.font = [UIFont systemFontOfSize:18];
  38. _textLabel.numberOfLines = 0;
  39. UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
  40. singleTap.numberOfTapsRequired = 1;
  41. _textLabel.userInteractionEnabled = YES;
  42. [_textLabel sizeToFit];
  43. [_textLabel addGestureRecognizer:singleTap];
  44. _borderView = [UIImageView new];
  45. _borderView.layer.borderWidth = 1;
  46. _borderView.layer.borderColor = Pink_Cor.CGColor;//UIColorFromRGB(0x0accac).CGColor;
  47. _borderView.userInteractionEnabled = YES;
  48. [self addSubview:_borderView];
  49. _deleteBtn = [UIButton new];
  50. [_deleteBtn setImage:[UIImage imageNamed:@"videotext_delete"] forState:UIControlStateNormal];
  51. [_deleteBtn addTarget:self action:@selector(onDeleteBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  52. [self addSubview:_deleteBtn];
  53. _styleBtn = [UIButton new];
  54. [_styleBtn setImage:[UIImage imageNamed:@"videotext_style"] forState:UIControlStateNormal];
  55. [_styleBtn addTarget:self action:@selector(onStyleBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  56. [self addSubview:_styleBtn];
  57. _scaleRotateBtn = [UIButton new];
  58. [_scaleRotateBtn setImage:[UIImage imageNamed:@"videotext_rotate"] forState:UIControlStateNormal];
  59. UIPanGestureRecognizer* panGensture = [[UIPanGestureRecognizer alloc] initWithTarget:self action: @selector (handlePanSlide:)];
  60. [self addSubview:_scaleRotateBtn];
  61. [_scaleRotateBtn addGestureRecognizer:panGensture];
  62. UIView* inputAccessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 40)];
  63. UIView* labelBgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, inputAccessoryView.width - 40, inputAccessoryView.height)];
  64. labelBgView.backgroundColor = UIColor.whiteColor;
  65. labelBgView.alpha = 0.5;
  66. [inputAccessoryView addSubview:labelBgView];
  67. _inputTextView = [[UITextView alloc] initWithFrame:CGRectMake(10, 0, inputAccessoryView.width - 50, inputAccessoryView.height)];
  68. _inputTextView.textColor = UIColorFromRGB(0xFFFFFF);
  69. _inputTextView.font = [UIFont systemFontOfSize:18];
  70. _inputTextView.textAlignment = NSTextAlignmentLeft;
  71. _inputTextView.delegate = self;
  72. _inputTextView.editable = YES;
  73. _inputTextView.backgroundColor = UIColor.clearColor;
  74. [inputAccessoryView addSubview:_inputTextView];
  75. _inputConfirmBtn = [[UIButton alloc] initWithFrame:CGRectMake(_inputTextView.right, 0, 40, inputAccessoryView.height)];
  76. _inputConfirmBtn.backgroundColor =Pink_Cor;// UIColorFromRGB(0x0accac);
  77. [_inputConfirmBtn setImage:[UIImage imageNamed:@"videotext_confirm"] forState:UIControlStateNormal];
  78. [_inputConfirmBtn addTarget:self action:@selector(onInputConfirmBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  79. [inputAccessoryView addSubview:_inputConfirmBtn];
  80. _hiddenTextField = [[UITextField alloc] initWithFrame:CGRectZero];
  81. _hiddenTextField.inputAccessoryView = inputAccessoryView;
  82. [self addSubview:_hiddenTextField];
  83. [_borderView addSubview:_textLabel];
  84. UIPanGestureRecognizer* selfPanGensture = [[UIPanGestureRecognizer alloc] initWithTarget:self action: @selector (handlePanSlide:)];
  85. [self addGestureRecognizer:selfPanGensture];
  86. UIPinchGestureRecognizer* pinchGensture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
  87. [self addGestureRecognizer:pinchGensture];
  88. UIRotationGestureRecognizer* rotateGensture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotate:)];
  89. [self addGestureRecognizer:rotateGensture];
  90. [[NSNotificationCenter defaultCenter] addObserver:self
  91. selector:@selector(changeFirstResponder)
  92. name:UIKeyboardDidShowNotification
  93. object:nil];
  94. _rotateAngle = 0.f;
  95. }
  96. return self;
  97. }
  98. - (void)layoutSubviews
  99. {
  100. [super layoutSubviews];
  101. CGPoint center = [self convertPoint:self.center fromView:self.superview];
  102. _borderView.bounds = CGRectMake(0, 0, _textLabel.width + 20, _textLabel.height + 10);
  103. _borderView.center = center;
  104. _textLabel.center = [_borderView convertPoint:_borderView.center fromView:self];
  105. _deleteBtn.center = CGPointMake(_borderView.x, _borderView.y);
  106. _deleteBtn.bounds = CGRectMake(0, 0, 30, 30);
  107. _styleBtn.center = CGPointMake(_borderView.right, _borderView.top);
  108. _styleBtn.bounds = CGRectMake(0, 0, 30, 30);
  109. _scaleRotateBtn.center = CGPointMake(_borderView.right, _borderView.bottom);
  110. _scaleRotateBtn.bounds = CGRectMake(0, 0, 30, 30);
  111. }
  112. - (NSString*)text
  113. {
  114. return _textLabel.text;
  115. }
  116. //生成字幕图片
  117. - (UIImage*)textImage
  118. {
  119. _borderView.layer.borderWidth = 0;
  120. [_borderView setNeedsDisplay];
  121. CGRect rect = _borderView.bounds;
  122. UIView *rotatedViewBox = [[UIView alloc]initWithFrame:CGRectMake(0, 0, rect.size.width , rect.size.height)];
  123. CGAffineTransform t = CGAffineTransformMakeRotation(_rotateAngle);
  124. rotatedViewBox.transform = t;
  125. CGSize rotatedSize = rotatedViewBox.frame.size;
  126. UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, 0.f);
  127. CGContextRef context = UIGraphicsGetCurrentContext();
  128. CGContextTranslateCTM(context, rotatedSize.width/2, rotatedSize.height/2);
  129. CGContextRotateCTM(context, _rotateAngle);
  130. //[_textLabel drawTextInRect:CGRectMake(-rect.size.width / 2, -rect.size.height / 2, rect.size.width, rect.size.height)];
  131. [_borderView drawViewHierarchyInRect:CGRectMake(-rect.size.width / 2, -rect.size.height / 2, rect.size.width, rect.size.height) afterScreenUpdates:YES];
  132. UIImage *rotatedImg = UIGraphicsGetImageFromCurrentImageContext();
  133. UIGraphicsEndImageContext();
  134. _borderView.layer.borderWidth = 1;
  135. _borderView.layer.borderColor = Pink_Cor.CGColor;//UIColorFromRGB(0x0accac).CGColor;
  136. return rotatedImg;
  137. }
  138. //字幕图在视频预览view的frame
  139. - (CGRect)textFrameOnView:(UIView *)view
  140. {
  141. CGRect frame = CGRectMake(_borderView.x, _borderView.y, _borderView.bounds.size.width, _borderView.bounds.size.height);
  142. if (![view.subviews containsObject:self]) {
  143. [view addSubview:self];
  144. CGRect rc = [self convertRect:frame toView:view];
  145. [self removeFromSuperview];
  146. return rc;
  147. }
  148. return [self convertRect:frame toView:view];
  149. }
  150. - (CGRect)textRect
  151. {
  152. CGRect rect = [_textLabel.text boundingRectWithSize:CGSizeMake(MAXFLOAT, 0) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName:_textLabel.font} context:nil];
  153. //限制最小的文字框大小
  154. if (rect.size.width < 30) {
  155. rect.size.width = 30;
  156. } else if (rect.size.height < 10) {
  157. rect.size.height = 10;
  158. }
  159. return rect;
  160. }
  161. - (void)resignFirstResponser
  162. {
  163. if (!_isInputting)
  164. return;
  165. _isInputting = NO;
  166. [_inputTextView resignFirstResponder];
  167. }
  168. - (void)changeFirstResponder
  169. {
  170. if (_isInputting) {
  171. //辅助唤出键盘后,键盘上的输入框设为实际输入点
  172. if ([_textLabel.text isEqualToString:kDefaultText]) {
  173. _textLabel.text = @"";
  174. } else {
  175. _inputTextView.text = _textLabel.text;
  176. }
  177. [_inputTextView becomeFirstResponder];
  178. } else {
  179. if (_hiddenTextField.isFirstResponder) {
  180. [_hiddenTextField resignFirstResponder];
  181. } else {
  182. [self resignFirstResponder];
  183. [_hiddenTextField resignFirstResponder];
  184. }
  185. }
  186. }
  187. #pragma mark - GestureRecognizer handle
  188. - (void)onTap:(UITapGestureRecognizer*)recognizer
  189. {
  190. _isInputting = YES;
  191. [_hiddenTextField becomeFirstResponder];
  192. }
  193. - (void)handlePanSlide:(UIPanGestureRecognizer*)recognizer
  194. {
  195. //拖动
  196. if (recognizer.view == self) {
  197. CGPoint translation = [recognizer translationInView:self.superview];
  198. CGPoint center = CGPointMake(recognizer.view.center.x + translation.x,
  199. recognizer.view.center.y + translation.y);
  200. if (center.x < 0) {
  201. center.x = 0;
  202. }
  203. else if (center.x > self.superview.width) {
  204. center.x = self.superview.width;
  205. }
  206. if (center.y < 0) {
  207. center.y = 0;
  208. }
  209. else if (center.y > self.superview.height) {
  210. center.y = self.superview.height;
  211. }
  212. recognizer.view.center = center;
  213. [recognizer setTranslation:CGPointZero inView:self.superview];
  214. }
  215. else if (recognizer.view == _scaleRotateBtn) {
  216. CGPoint translation = [recognizer translationInView:self];
  217. //放大
  218. if (recognizer.state == UIGestureRecognizerStateChanged) {
  219. if (translation.y == 0.0 || fabs(translation.x / translation.y) > 3.0) {
  220. CGFloat delta = translation.x / 3;
  221. CGFloat newFontSize = MAX(10.0f, MIN(150.f, _textLabel.font.pointSize + delta));
  222. _textLabel.font = [UIFont systemFontOfSize:newFontSize];
  223. _textLabel.bounds = [self textRect];
  224. self.bounds = CGRectMake(0, 0, _textLabel.bounds.size.width + 50, _textLabel.bounds.size.height + 40);
  225. }
  226. //旋转
  227. else {
  228. CGPoint newCenter = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);
  229. CGPoint anthorPoint = _textLabel.center;
  230. CGFloat height = newCenter.y - anthorPoint.y;
  231. CGFloat width = newCenter.x - anthorPoint.x;
  232. CGFloat angle1 = atan(height / width);
  233. height = recognizer.view.center.y - anthorPoint.y;
  234. width = recognizer.view.center.x - anthorPoint.x;
  235. CGFloat angle2 = atan(height / width);
  236. CGFloat angle = angle1 - angle2;
  237. self.transform = CGAffineTransformRotate(self.transform, angle);
  238. _rotateAngle += angle;
  239. }
  240. }
  241. [recognizer setTranslation:CGPointZero inView:self];
  242. }
  243. }
  244. //双手指放大
  245. - (void)handlePinch:(UIPinchGestureRecognizer*)recognizer
  246. {
  247. CGFloat newFontSize = MAX(10.0f, MIN(150.f, _textLabel.font.pointSize * recognizer.scale));
  248. // set font size
  249. _textLabel.font = [_textLabel.font fontWithSize:newFontSize];
  250. CGRect rect = [self textRect];
  251. rect = [_textLabel convertRect:rect toView:self];
  252. _textLabel.bounds = CGRectMake(0, 0, rect.size.width, rect.size.height);
  253. self.bounds = CGRectMake(0, 0, _textLabel.bounds.size.width + 50, _textLabel.bounds.size.height + 40);
  254. recognizer.scale = 1;
  255. }
  256. //双手指旋转
  257. - (void)handleRotate:(UIRotationGestureRecognizer*)recognizer
  258. {
  259. recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
  260. _rotateAngle += recognizer.rotation;
  261. recognizer.rotation = 0;
  262. }
  263. #pragma mark - UI event handle
  264. - (void)onInputConfirmBtnClicked:(UIButton*)sender
  265. {
  266. _isInputting = NO;
  267. [_inputTextView resignFirstResponder];
  268. [_hiddenTextField resignFirstResponder];
  269. _textLabel.text = _inputTextView.text;
  270. ;
  271. _textLabel.bounds = [self textRect];
  272. self.bounds = CGRectMake(0, 0, _textLabel.bounds.size.width + 50, _textLabel.bounds.size.height + 40);
  273. [self.delegate onTextInputDone:_textLabel.text];
  274. }
  275. - (void)onDeleteBtnClicked:(UIButton*)sender
  276. {
  277. [self.delegate onRemoveTextField:self];
  278. [self removeFromSuperview];
  279. }
  280. - (void)onStyleBtnClicked:(UIButton*)sender
  281. {
  282. //样式设计
  283. //样式设计
  284. _styleIndex = (_styleIndex + 1) % 7;
  285. switch (_styleIndex) {
  286. case 0: {
  287. _textLabel.textColor = UIColor.whiteColor;
  288. _textLabel.shadowColor = nil;
  289. _borderView.backgroundColor = UIColor.clearColor;
  290. break;
  291. }
  292. case 1: {
  293. _borderView.backgroundColor = UIColor.blackColor;
  294. break;
  295. }
  296. case 2: {
  297. _textLabel.textColor = UIColor.blackColor;
  298. _textLabel.shadowColor = nil;
  299. _borderView.backgroundColor = UIColor.clearColor;
  300. break;
  301. }
  302. case 3: {
  303. _borderView.backgroundColor = UIColor.whiteColor;
  304. break;
  305. }
  306. case 4: {
  307. _textLabel.textColor = UIColor.redColor;
  308. _textLabel.shadowColor = nil;
  309. _borderView.backgroundColor = UIColor.clearColor;
  310. break;
  311. }
  312. case 5: {
  313. _borderView.backgroundColor = UIColor.whiteColor;
  314. break;
  315. }
  316. case 6: {
  317. _borderView.backgroundColor = UIColor.blackColor;
  318. break;
  319. }
  320. default:
  321. break;
  322. }
  323. }
  324. - (void)dealloc
  325. {
  326. [[NSNotificationCenter defaultCenter] removeObserver:self];
  327. }
  328. @end