SLEditImageController.m 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. //
  2. // SLEditImageController.m
  3. // DarkMode
  4. //
  5. // Created by wsl on 2019/10/31.
  6. // Copyright © 2019 wsl. All rights reserved.
  7. //
  8. #import "SLEditImageController.h"
  9. #import <Photos/Photos.h>
  10. #import "UIView+SLImage.h"
  11. #import "SLBlurView.h"
  12. #import "SLEditMenuView.h"
  13. #import "SLEditSelectedBox.h"
  14. #import "SLImage.h"
  15. #import "SLImageView.h"
  16. #import "SLDrawView.h"
  17. #import "SLEditTextView.h"
  18. #import "SLMosaicView.h"
  19. #import "UIImage+SLCommon.h"
  20. #import "SLImageZoomView.h"
  21. #import "SLImageClipController.h"
  22. @interface SLEditImageController ()<UIGestureRecognizerDelegate, SLImageZoomViewDelegate>
  23. @property (nonatomic, strong) SLImageZoomView *zoomView; // 预览视图 展示编辑的图片 可以缩放
  24. @property (nonatomic, strong) SLBlurView *editBtn; //编辑
  25. @property (nonatomic, strong) SLBlurView *againShotBtn; // 再拍一次
  26. @property (nonatomic, strong) UIButton *saveAlbumBtn; //保存到相册
  27. @property (nonatomic, strong) UIButton *cancleEditBtn; //取消编辑
  28. @property (nonatomic, strong) UIButton *doneEditBtn; //完成编辑
  29. @property (nonatomic, strong) SLEditMenuView *editMenuView; //编辑菜单栏
  30. @property (nonatomic, strong) UIButton *trashTips; //垃圾桶提示 拖拽删除 贴图或文字
  31. @property (nonatomic, strong) SLDrawView *drawView; // 涂鸦视图
  32. @property (nonatomic, strong) NSMutableArray *watermarkArray; // 水印层 所有的贴图和文本
  33. @property (nonatomic, strong) SLEditSelectedBox *selectedBox; //水印选中框
  34. @property (nonatomic, strong) SLMosaicView *mosaicView; //马赛克画板
  35. @property (nonatomic, assign) SLEditMenuType editingMenuType; //当前正在编辑的菜单类型
  36. @end
  37. @implementation SLEditImageController
  38. #pragma mark - Override
  39. - (void)viewDidLoad {
  40. [super viewDidLoad];
  41. [self setupUI];
  42. }
  43. - (void)viewWillDisappear:(BOOL)animated {
  44. [super viewWillDisappear:animated];
  45. }
  46. - (BOOL)prefersStatusBarHidden {
  47. return YES;
  48. }
  49. - (void)dealloc {
  50. [[NSNotificationCenter defaultCenter] removeObserver:self];
  51. NSLog(@"图片编辑视图释放了");
  52. }
  53. #pragma mark - UI
  54. - (void)setupUI {
  55. self.view.backgroundColor = [UIColor blackColor];
  56. [self.view addSubview:self.zoomView];
  57. self.zoomView.pinchGestureRecognizer.enabled = NO;
  58. self.zoomView.image = self.image;
  59. if (self.image.size.width > 0) {
  60. self.zoomView.imageView.frame = CGRectMake(0, 0, self.zoomView.sl_width, self.zoomView.sl_width * self.image.size.height/self.image.size.width);
  61. }
  62. if (self.zoomView.imageView.sl_height <= self.zoomView.sl_height) {
  63. self.zoomView.imageView.center = CGPointMake(self.zoomView.sl_width/2.0, self.zoomView.sl_height/2.0);
  64. }
  65. //添加裁剪完成监听
  66. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imageClippingComplete:) name:@"sl_ImageClippingComplete" object:nil];
  67. [self.view addSubview:self.againShotBtn];
  68. if (!_isCheckBody) {
  69. [self.view addSubview:self.editBtn];
  70. }
  71. [self.view addSubview:self.saveAlbumBtn];
  72. [self.view addSubview:self.cancleEditBtn];
  73. [self.view addSubview:self.doneEditBtn];
  74. }
  75. #pragma mark - HelpMethods
  76. // 添加拖拽、缩放、旋转、单击、双击手势
  77. - (void)addRotateAndPinchGestureRecognizer:(UIView *)view {
  78. //单击手势选中
  79. UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)];
  80. singleTap.numberOfTapsRequired = 1;
  81. singleTap.numberOfTouchesRequired = 1;
  82. [view addGestureRecognizer:singleTap];
  83. if ([view isKindOfClass:[UILabel class]]) {
  84. UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapAction:)];
  85. doubleTap.numberOfTapsRequired = 2;
  86. doubleTap.numberOfTouchesRequired = 1;
  87. [singleTap requireGestureRecognizerToFail:doubleTap];
  88. [view addGestureRecognizer:doubleTap];
  89. }
  90. //拖拽手势
  91. UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dragAction:)];
  92. pan.minimumNumberOfTouches = 1;
  93. [view addGestureRecognizer:pan];
  94. //缩放手势
  95. UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self
  96. action:@selector(pinchAction:)];
  97. pinchGestureRecognizer.delegate = self;
  98. [view addGestureRecognizer:pinchGestureRecognizer];
  99. //旋转手势
  100. UIRotationGestureRecognizer *rotateRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self
  101. action:@selector(rotateAction:)];
  102. [view addGestureRecognizer:rotateRecognizer];
  103. rotateRecognizer.delegate = self;
  104. }
  105. //置顶视图
  106. - (void)topSelectedView:(UIView *)topView {
  107. [self.zoomView.imageView bringSubviewToFront:topView];
  108. [self.watermarkArray removeObject:topView];
  109. [self.watermarkArray addObject:topView];
  110. [SLDelayPerform sl_cancelDelayPerform]; //取消延迟执行
  111. self.selectedBox.frame = topView.bounds;
  112. [topView addSubview:self.selectedBox];
  113. }
  114. // 隐藏预览按钮
  115. - (void)hiddenPreviewButton:(BOOL)isHidden {
  116. self.againShotBtn.hidden = isHidden;
  117. self.editBtn.hidden = isHidden;
  118. self.saveAlbumBtn.hidden = isHidden;
  119. }
  120. // 隐藏编辑时菜单按钮
  121. - (void)hiddenEditMenus:(BOOL)isHidden {
  122. self.cancleEditBtn.hidden = isHidden;
  123. self.doneEditBtn.hidden = isHidden;
  124. self.editMenuView.hidden = isHidden;
  125. }
  126. #pragma mark - Setter
  127. - (void)setEditingMenuType:(SLEditMenuType)editingMenuType {
  128. _editingMenuType = editingMenuType;
  129. switch (_editingMenuType) {
  130. case SLEditMenuTypeUnknown:
  131. self.zoomView.scrollEnabled = YES;
  132. self.zoomView.pinchGestureRecognizer.enabled = YES;
  133. break;
  134. case SLEditMenuTypeGraffiti:
  135. self.zoomView.pinchGestureRecognizer.enabled = YES;
  136. self.zoomView.scrollEnabled = NO;
  137. break;
  138. case SLEditMenuTypeText:
  139. self.zoomView.scrollEnabled = YES;
  140. self.zoomView.pinchGestureRecognizer.enabled = NO;
  141. break;
  142. case SLEditMenuTypeSticking:
  143. self.zoomView.scrollEnabled = YES;
  144. self.zoomView.pinchGestureRecognizer.enabled = NO;
  145. break;
  146. case SLEditMenuTypePictureMosaic:
  147. self.zoomView.scrollEnabled = NO;
  148. self.zoomView.pinchGestureRecognizer.enabled = YES;
  149. break;
  150. case SLEditMenuTypePictureClipping:
  151. self.zoomView.scrollEnabled = YES;
  152. self.zoomView.pinchGestureRecognizer.enabled = YES;
  153. break;
  154. default:
  155. break;
  156. }
  157. }
  158. #pragma mark - Getter
  159. - (SLImageZoomView *)zoomView {
  160. if (_zoomView == nil) {
  161. _zoomView = [[SLImageZoomView alloc] initWithFrame:self.view.bounds];
  162. _zoomView.backgroundColor = [UIColor blackColor];
  163. _zoomView.userInteractionEnabled = YES;
  164. _zoomView.maximumZoomScale = 4;
  165. _zoomView.zoomViewDelegate = self;
  166. }
  167. return _zoomView;
  168. }
  169. - (SLBlurView *)editBtn {
  170. if (_editBtn == nil) {
  171. _editBtn = [[SLBlurView alloc] initWithFrame:CGRectMake(0, 0, 70, 70)];
  172. _editBtn.center = CGPointMake(self.view.sl_width/2.0, self.view.sl_height - 80);
  173. _editBtn.layer.cornerRadius = _editBtn.sl_width/2.0;
  174. UIButton * btn = [[UIButton alloc] initWithFrame:_editBtn.bounds];
  175. [btn setImage:[UIImage imageNamed:@"edit"] forState:UIControlStateNormal];
  176. [btn addTarget:self action:@selector(editBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  177. [_editBtn addSubview:btn];
  178. }
  179. return _editBtn;
  180. }
  181. - (SLBlurView *)againShotBtn {
  182. if (_againShotBtn == nil) {
  183. _againShotBtn = [[SLBlurView alloc] initWithFrame:CGRectMake(0, 0, 70, 70)];
  184. _againShotBtn.center = CGPointMake((self.view.sl_width/2 - 70/2.0)/2.0, self.view.sl_height - 80);
  185. _againShotBtn.layer.cornerRadius = _againShotBtn.sl_width/2.0;
  186. UIButton * btn = [[UIButton alloc] initWithFrame:_againShotBtn.bounds];
  187. [btn setImage:[UIImage imageNamed:@"cancle"] forState:UIControlStateNormal];
  188. [btn addTarget:self action:@selector(againShotBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  189. [_againShotBtn addSubview:btn];
  190. }
  191. return _againShotBtn;
  192. }
  193. - (UIButton *)saveAlbumBtn {
  194. if (_saveAlbumBtn == nil) {
  195. _saveAlbumBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 70, 70)];
  196. _saveAlbumBtn.center = CGPointMake(self.view.sl_width/2.0 + 70/2.0+ (self.view.sl_width/2 - 70/2.0)/2.0, self.view.sl_height - 80);
  197. _saveAlbumBtn.layer.cornerRadius = _saveAlbumBtn.sl_width/2.0;
  198. _saveAlbumBtn.backgroundColor = [UIColor whiteColor];
  199. [_saveAlbumBtn setImage:[UIImage imageNamed:@"save"] forState:UIControlStateNormal];
  200. [_saveAlbumBtn addTarget:self action:@selector(saveAlbumBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  201. }
  202. return _saveAlbumBtn;
  203. }
  204. - (UIButton *)cancleEditBtn {
  205. if (_cancleEditBtn == nil) {
  206. _cancleEditBtn = [[UIButton alloc] initWithFrame:CGRectMake(15, 30, 40, 30)];
  207. _cancleEditBtn.hidden = YES;
  208. [_cancleEditBtn setTitle:@"取消" forState:UIControlStateNormal];
  209. [_cancleEditBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  210. _cancleEditBtn.titleLabel.font = [UIFont systemFontOfSize:14];
  211. [_cancleEditBtn addTarget:self action:@selector(cancleEditBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  212. }
  213. return _cancleEditBtn;
  214. }
  215. - (UIButton *)doneEditBtn {
  216. if (_doneEditBtn == nil) {
  217. _doneEditBtn = [[UIButton alloc] initWithFrame:CGRectMake(self.view.sl_width - 50 - 15, 30, 40, 30)];
  218. _doneEditBtn.hidden = YES;
  219. _doneEditBtn.backgroundColor = [UIColor colorWithRed:45/255.0 green:175/255.0 blue:45/255.0 alpha:1];
  220. [_doneEditBtn setTitle:@"完成" forState:UIControlStateNormal];
  221. [_doneEditBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  222. _doneEditBtn.titleLabel.font = [UIFont systemFontOfSize:14];
  223. _doneEditBtn.layer.cornerRadius = 4;
  224. [_doneEditBtn addTarget:self action:@selector(doneEditBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  225. }
  226. return _doneEditBtn;
  227. }
  228. - (SLEditMenuView *)editMenuView {
  229. if (!_editMenuView) {
  230. _editMenuView = [[SLEditMenuView alloc] initWithFrame:CGRectMake(0, self.view.sl_height - 80 - 60, self.view.sl_width, 80 + 60)];
  231. _editMenuView.hidden = YES;
  232. __weak typeof(self) weakSelf = self;
  233. _editMenuView.editObject = SLEditObjectPicture;
  234. _editMenuView.selectEditMenu = ^(SLEditMenuType editMenuType, NSDictionary * _Nullable setting) {
  235. weakSelf.editingMenuType = ![setting[@"hidden"] boolValue] ? editMenuType : SLEditMenuTypeUnknown;
  236. if (editMenuType == SLEditMenuTypeGraffiti) {
  237. weakSelf.drawView.userInteractionEnabled = ![setting[@"hidden"] boolValue];
  238. if ([setting[@"hidden"] boolValue]) weakSelf.editingMenuType = SLEditMenuTypeUnknown;
  239. [weakSelf.zoomView.imageView insertSubview:weakSelf.drawView atIndex:([weakSelf.zoomView.imageView.subviews containsObject:weakSelf.mosaicView] ? 1: 0)];
  240. if (setting[@"lineColor"]) {
  241. weakSelf.drawView.lineColor = setting[@"lineColor"];
  242. }
  243. if (setting[@"goBack"]) {
  244. [weakSelf.drawView goBack];
  245. }
  246. }else {
  247. weakSelf.drawView.userInteractionEnabled = NO;
  248. }
  249. if (editMenuType == SLEditMenuTypeSticking) {
  250. SLImage *image = setting[@"image"];
  251. if ([setting[@"hidden"] boolValue]) weakSelf.editingMenuType = SLEditMenuTypeUnknown;
  252. if (image) {
  253. SLImageView *imageView = [[SLImageView alloc] initWithFrame:CGRectMake(0, 0, image.size.width/[UIScreen mainScreen].scale, image.size.height/[UIScreen mainScreen].scale)];
  254. imageView.autoPlayAnimatedImage = NO;
  255. imageView.userInteractionEnabled = YES;
  256. CGRect imageRect = [weakSelf.zoomView convertRect:weakSelf.zoomView.imageView.frame toView:weakSelf.view];
  257. CGPoint center = CGPointZero;
  258. center.x = fabs(imageRect.origin.x)+weakSelf.zoomView.sl_width/2.0;
  259. center.y = 0;
  260. if (imageRect.origin.y >= 0 && imageRect.size.height <= weakSelf.zoomView.sl_height) {
  261. center.y = imageRect.size.height/2.0;
  262. }else {
  263. center.y = fabs(imageRect.origin.y) + weakSelf.zoomView.sl_height/2.0;
  264. }
  265. imageView.transform = CGAffineTransformMakeScale(1/weakSelf.zoomView.zoomScale, 1/weakSelf.zoomView.zoomScale);
  266. center = CGPointMake(center.x/weakSelf.zoomView.zoomScale, center.y/weakSelf.zoomView.zoomScale);
  267. imageView.center = center;
  268. imageView.image = image;
  269. [weakSelf.watermarkArray addObject:imageView];
  270. [weakSelf.zoomView.imageView addSubview:imageView];
  271. [weakSelf addRotateAndPinchGestureRecognizer:imageView];
  272. [weakSelf topSelectedView:imageView];
  273. [SLDelayPerform sl_startDelayPerform:^{
  274. [weakSelf.selectedBox removeFromSuperview];
  275. } afterDelay:1.0];
  276. }
  277. }
  278. if (editMenuType == SLEditMenuTypeText) {
  279. SLEditTextView *editTextView = [[SLEditTextView alloc] initWithFrame:CGRectMake(0, 0, SL_kScreenWidth, SL_kScreenHeight)];
  280. [weakSelf.view addSubview:editTextView];
  281. if ([setting[@"hidden"] boolValue]) weakSelf.editingMenuType = SLEditMenuTypeUnknown;
  282. editTextView.editTextCompleted = ^(UILabel * _Nullable label) {
  283. if (label.text.length == 0 || label == nil) {
  284. return;
  285. }
  286. CGRect imageRect = [weakSelf.zoomView convertRect:weakSelf.zoomView.imageView.frame toView:weakSelf.view];
  287. CGPoint center = CGPointZero;
  288. center.x = fabs(imageRect.origin.x)+weakSelf.zoomView.sl_width/2.0;
  289. center.y = 0;
  290. if (imageRect.origin.y >= 0 && imageRect.size.height <= weakSelf.zoomView.sl_height) {
  291. center.y = imageRect.size.height/2.0;
  292. }else {
  293. center.y = fabs(imageRect.origin.y) + weakSelf.zoomView.sl_height/2.0;
  294. }
  295. label.transform = CGAffineTransformMakeScale(1/weakSelf.zoomView.zoomScale, 1/weakSelf.zoomView.zoomScale);
  296. center = CGPointMake(center.x/weakSelf.zoomView.zoomScale, center.y/weakSelf.zoomView.zoomScale);
  297. label.center = center;
  298. [weakSelf.zoomView.imageView addSubview:label];
  299. [weakSelf.watermarkArray addObject:label];
  300. [weakSelf addRotateAndPinchGestureRecognizer:label];
  301. [weakSelf topSelectedView:label];
  302. [SLDelayPerform sl_startDelayPerform:^{
  303. [weakSelf.selectedBox removeFromSuperview];
  304. } afterDelay:1.0];
  305. };
  306. }
  307. if(editMenuType == SLEditMenuTypePictureMosaic) {
  308. if (setting[@"mosaicType"]) {
  309. weakSelf.mosaicView.userInteractionEnabled = ![setting[@"hidden"] boolValue];
  310. if ([setting[@"hidden"] boolValue]) weakSelf.editingMenuType = SLEditMenuTypeUnknown;
  311. weakSelf.mosaicView.mosaicType = [setting[@"mosaicType"] integerValue];
  312. [weakSelf.zoomView.imageView insertSubview:weakSelf.mosaicView atIndex:0];
  313. }
  314. if (setting[@"goBack"]) {
  315. [weakSelf.mosaicView goBack];
  316. }
  317. }else {
  318. weakSelf.mosaicView.userInteractionEnabled = NO;
  319. }
  320. if (editMenuType == SLEditMenuTypePictureClipping) {
  321. SLImageClipController *imageClipController = [[SLImageClipController alloc] init];
  322. imageClipController.modalPresentationStyle = UIModalPresentationFullScreen;
  323. [weakSelf.selectedBox removeFromSuperview];
  324. UIImage *image = [weakSelf.zoomView.imageView sl_imageByViewInRect:weakSelf.zoomView.imageView.bounds];
  325. imageClipController.image = image;
  326. [weakSelf presentViewController:imageClipController animated:NO completion:nil];
  327. }
  328. };
  329. [self.view addSubview:_editMenuView];
  330. }
  331. return _editMenuView;
  332. }
  333. - (UIButton *)trashTips {
  334. if (!_trashTips) {
  335. _trashTips = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
  336. _trashTips.center = CGPointMake(SL_kScreenWidth/2.0, SL_kScreenHeight - 60);
  337. [_trashTips setTitle:@"拖动到此处删除" forState:UIControlStateNormal];
  338. [_trashTips setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  339. _trashTips.titleLabel.font = [UIFont systemFontOfSize:14];
  340. }
  341. return _trashTips;
  342. }
  343. - (SLDrawView *)drawView {
  344. if (!_drawView) {
  345. _drawView = [[SLDrawView alloc] initWithFrame:self.zoomView.imageView.bounds];
  346. _drawView.backgroundColor = [UIColor clearColor];
  347. _drawView.lineWidth = 5.0;
  348. __weak typeof(self) weakSelf = self;
  349. _drawView.drawBegan = ^{
  350. [weakSelf hiddenEditMenus:YES];
  351. };
  352. _drawView.drawEnded = ^{
  353. [weakSelf hiddenEditMenus:NO];
  354. };
  355. }
  356. return _drawView;
  357. }
  358. - (NSMutableArray *)watermarkArray {
  359. if (!_watermarkArray) {
  360. _watermarkArray = [NSMutableArray array];
  361. }
  362. return _watermarkArray;
  363. }
  364. - (SLEditSelectedBox *)selectedBox {
  365. if (!_selectedBox) {
  366. _selectedBox = [[SLEditSelectedBox alloc] init];
  367. }
  368. return _selectedBox;
  369. }
  370. - (SLMosaicView *)mosaicView {
  371. if (!_mosaicView) {
  372. _mosaicView = [[SLMosaicView alloc] initWithFrame:self.zoomView.imageView.bounds];
  373. __weak typeof(self) weakSelf = self;
  374. _mosaicView.squareWidth = 15;
  375. _mosaicView.paintSize = CGSizeMake(40, 40);
  376. _mosaicView.brushColor = ^UIColor *(CGPoint point) {
  377. point.x = point.x/weakSelf.view.frame.size.width*weakSelf.zoomView.image.size.width;
  378. point.y = point.y/weakSelf.view.frame.size.height*weakSelf.zoomView.image.size.height;
  379. point.x = point.x/self.zoomView.zoomScale;
  380. point.y = point.y/self.zoomView.zoomScale;
  381. return [weakSelf.zoomView.image sl_colorAtPixel:point];
  382. };
  383. _mosaicView.brushBegan = ^{
  384. [weakSelf hiddenEditMenus:YES];
  385. };
  386. _mosaicView.brushEnded = ^{
  387. [weakSelf hiddenEditMenus:NO];
  388. };
  389. _mosaicView.userInteractionEnabled = YES;
  390. }
  391. return _mosaicView;
  392. }
  393. #pragma mark - Events Handle
  394. //编辑
  395. - (void)editBtnClicked:(id)sender {
  396. self.zoomView.pinchGestureRecognizer.enabled = YES;
  397. [self hiddenEditMenus:NO];
  398. [self hiddenPreviewButton:YES];
  399. }
  400. //再试一次 继续拍摄
  401. - (void)againShotBtnClicked:(id)sender {
  402. [self dismissViewControllerAnimated:NO completion:nil];
  403. }
  404. //保存到相册
  405. - (void)saveAlbumBtnClicked:(id)sender {
  406. if(self.image && self.editPhotoBlock) {
  407. [self dismissViewControllerAnimated:NO completion:^{
  408. self.editPhotoBlock(self.image);
  409. }];
  410. // UIImageWriteToSavedPhotosAlbum(self.image, self, @selector(savedPhotoImage:didFinishSavingWithError:contextInfo:), nil);
  411. }
  412. }
  413. - (void)initEditPhotoBlock:(EditPhotoBlock)block {
  414. self.editPhotoBlock = block;
  415. }
  416. //保存图片完成后调用的方法
  417. - (void)savedPhotoImage:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo: (void *)contextInfo {
  418. SL_DISPATCH_ON_MAIN_THREAD(^{
  419. [self againShotBtnClicked:nil];
  420. });
  421. if (error) {
  422. NSLog(@"保存图片出错%@", error.localizedDescription);
  423. } else {
  424. NSLog(@"保存图片成功");
  425. }
  426. }
  427. //取消编辑
  428. - (void)cancleEditBtnClicked:(id)sender {
  429. [self hiddenPreviewButton:NO];
  430. [self hiddenEditMenus:YES];
  431. [self.selectedBox removeFromSuperview];
  432. [_editMenuView removeFromSuperview];
  433. _editMenuView = nil;
  434. [_drawView removeFromSuperview];
  435. _drawView = nil;
  436. [_mosaicView removeFromSuperview];
  437. _mosaicView = nil;
  438. for (UIView *view in self.watermarkArray) {
  439. [view removeFromSuperview];
  440. }
  441. [self.watermarkArray removeAllObjects];
  442. self.zoomView.zoomScale = 1;
  443. self.zoomView.image = self.image;
  444. self.zoomView.pinchGestureRecognizer.enabled = NO;
  445. self.zoomView.imageView.frame = CGRectMake(0, 0, self.zoomView.sl_width, self.zoomView.sl_width * self.image.size.height/self.image.size.width);
  446. if (self.zoomView.imageView.sl_height <= self.zoomView.sl_height) {
  447. self.zoomView.imageView.center = CGPointMake(self.zoomView.sl_width/2.0, self.zoomView.sl_height/2.0);
  448. }
  449. self.zoomView.contentSize = CGSizeMake(self.zoomView.imageView.sl_width, self.zoomView.imageView.sl_height);
  450. }
  451. //完成编辑 导出编辑后的对象
  452. - (void)doneEditBtnClicked:(id)sender {
  453. [self.selectedBox removeFromSuperview];
  454. self.image = [self.zoomView.imageView sl_imageByViewInRect:self.zoomView.imageView.bounds];
  455. [self cancleEditBtnClicked:nil];
  456. }
  457. // 点击水印视图
  458. - (void)singleTapAction:(UITapGestureRecognizer *)singleTap {
  459. [self topSelectedView:singleTap.view];
  460. if (singleTap.state == UIGestureRecognizerStateFailed || singleTap.state == UIGestureRecognizerStateEnded) {
  461. [SLDelayPerform sl_startDelayPerform:^{
  462. [self.selectedBox removeFromSuperview];
  463. } afterDelay:1.0];
  464. }
  465. }
  466. //双击 文本水印 开始编辑文本
  467. - (void)doubleTapAction:(UITapGestureRecognizer *)doubleTap {
  468. [self topSelectedView:doubleTap.view];
  469. doubleTap.view.hidden = YES;
  470. UILabel *tapLabel = (UILabel *)doubleTap.view;
  471. SLEditTextView *editTextView = [[SLEditTextView alloc] initWithFrame:CGRectMake(0, 0, SL_kScreenWidth, SL_kScreenHeight)];
  472. editTextView.configureEditParameters(@{@"textColor":tapLabel.textColor, @"backgroundColor":tapLabel.backgroundColor, @"text":tapLabel.text});
  473. editTextView.editTextCompleted = ^(UILabel * _Nullable label) {
  474. doubleTap.view.hidden = NO;
  475. if (label == nil) {
  476. return;
  477. }
  478. label.transform = tapLabel.transform;
  479. label.center = tapLabel.center;
  480. [tapLabel removeFromSuperview];
  481. [self.watermarkArray removeObject:tapLabel];
  482. [self.watermarkArray addObject:label];
  483. [self.zoomView.imageView addSubview:label];
  484. [self addRotateAndPinchGestureRecognizer:label];
  485. [self topSelectedView:label];
  486. [SLDelayPerform sl_startDelayPerform:^{
  487. [self.selectedBox removeFromSuperview];
  488. } afterDelay:1.0];
  489. };
  490. [self.view addSubview:editTextView];
  491. }
  492. // 拖拽 水印视图
  493. - (void)dragAction:(UIPanGestureRecognizer *)pan {
  494. // 返回的是相对于最原始的手指的偏移量
  495. CGPoint transP = [pan translationInView:self.zoomView.imageView];
  496. if (pan.state == UIGestureRecognizerStateBegan) {
  497. self.zoomView.imageView.clipsToBounds = NO;
  498. [self hiddenEditMenus:YES];
  499. [self.view addSubview:self.trashTips];
  500. [self topSelectedView:pan.view];
  501. } else if (pan.state == UIGestureRecognizerStateChanged ) {
  502. pan.view.center = CGPointMake(pan.view.center.x + transP.x, pan.view.center.y + transP.y);
  503. [pan setTranslation:CGPointZero inView:self.zoomView.imageView];
  504. //获取拖拽的视图在屏幕上的位置
  505. CGRect rect = [pan.view convertRect: pan.view.bounds toView:self.view];
  506. //是否删除 删除视图Y < 视图中心点Y坐标
  507. if (self.trashTips.center.y < rect.origin.y+rect.size.height/2.0) {
  508. [self.trashTips setTitle:@"松手即可删除" forState:UIControlStateNormal];
  509. [self.trashTips setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
  510. }else {
  511. [self.trashTips setTitle:@"拖动到此处删除" forState:UIControlStateNormal];
  512. [self.trashTips setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  513. }
  514. } else if (pan.state == UIGestureRecognizerStateFailed || pan.state == UIGestureRecognizerStateEnded) {
  515. [self hiddenEditMenus:NO];
  516. self.zoomView.imageView.clipsToBounds = YES;
  517. //获取拖拽的视图在屏幕上的位置
  518. CGRect rect = [pan.view convertRect: pan.view.bounds toView:self.view];
  519. CGRect imageRect = [self.zoomView convertRect:self.zoomView.imageView.frame toView:self.view];
  520. //删除拖拽的视图
  521. if (self.trashTips.center.y < rect.origin.y+rect.size.height/2.0) {
  522. [pan.view removeFromSuperview];
  523. [self.watermarkArray removeObject:(SLImageView *)pan.view];
  524. }else if (!CGRectIntersectsRect(imageRect, rect)) {
  525. //如果出了父视图zoomView的范围,则置于父视图中心
  526. CGPoint center = CGPointZero;
  527. center.x = fabs(imageRect.origin.x)+self.zoomView.sl_width/2.0;
  528. center.y = 0;
  529. if (imageRect.origin.y >= 0 && imageRect.size.height <= self.zoomView.sl_height) {
  530. center.y = imageRect.size.height/2.0;
  531. }else {
  532. center.y = fabs(imageRect.origin.y) + self.zoomView.sl_height/2.0;
  533. }
  534. center = CGPointMake(center.x/self.zoomView.zoomScale, center.y/self.zoomView.zoomScale);
  535. pan.view.center = center;
  536. }
  537. [self.trashTips removeFromSuperview];
  538. [SLDelayPerform sl_startDelayPerform:^{
  539. [self.selectedBox removeFromSuperview];
  540. } afterDelay:1.0];
  541. }
  542. }
  543. //缩放 水印视图
  544. - (void)pinchAction:(UIPinchGestureRecognizer *)pinch {
  545. if (pinch.state == UIGestureRecognizerStateBegan) {
  546. [self topSelectedView:pinch.view];
  547. self.zoomView.pinchGestureRecognizer.enabled = NO;
  548. self.zoomView.imageView.clipsToBounds = NO;
  549. }else if (pinch.state == UIGestureRecognizerStateFailed || pinch.state == UIGestureRecognizerStateEnded){
  550. [SLDelayPerform sl_startDelayPerform:^{
  551. [self.selectedBox removeFromSuperview];
  552. } afterDelay:1.0];
  553. self.zoomView.pinchGestureRecognizer.enabled = YES;
  554. self.zoomView.imageView.clipsToBounds = YES;
  555. }
  556. pinch.view.transform = CGAffineTransformScale(pinch.view.transform, pinch.scale, pinch.scale);
  557. pinch.scale = 1.0;
  558. }
  559. //旋转 水印视图 注意:旋转之后的frame会变!!!
  560. - (void)rotateAction:(UIRotationGestureRecognizer *)rotation {
  561. if (rotation.state == UIGestureRecognizerStateBegan) {
  562. [self topSelectedView:rotation.view];
  563. }else if (rotation.state == UIGestureRecognizerStateFailed || rotation.state == UIGestureRecognizerStateEnded){
  564. [SLDelayPerform sl_startDelayPerform:^{
  565. [self.selectedBox removeFromSuperview];
  566. } afterDelay:1.0];
  567. }
  568. rotation.view.transform = CGAffineTransformRotate(rotation.view.transform, rotation.rotation);
  569. // 将旋转的弧度清零(注意不是将图片旋转的弧度清零, 而是将当前手指旋转的弧度清零)
  570. rotation.rotation = 0;
  571. }
  572. // 图片裁剪完成
  573. - (void)imageClippingComplete:(NSNotification *)notification {
  574. UIImage *clipImage = notification.userInfo[@"image"];
  575. self.zoomView.zoomScale = 1;
  576. self.zoomView.image = clipImage;
  577. self.zoomView.imageView.frame = CGRectMake(0, 0, self.zoomView.sl_width, self.zoomView.sl_width * clipImage.size.height/clipImage.size.width);
  578. if (self.zoomView.imageView.sl_height <= self.zoomView.sl_height) {
  579. self.zoomView.imageView.center = CGPointMake(self.zoomView.sl_width/2.0, self.zoomView.sl_height/2.0);
  580. }
  581. self.zoomView.contentSize = CGSizeMake(self.zoomView.imageView.sl_width, self.zoomView.imageView.sl_height);
  582. _drawView.frame = self.zoomView.imageView.bounds;
  583. _mosaicView.frame = self.zoomView.imageView.bounds;
  584. [_drawView clear];
  585. [_mosaicView clear];
  586. for (UIView *view in self.watermarkArray) {
  587. [view removeFromSuperview];
  588. }
  589. [self.watermarkArray removeAllObjects];
  590. }
  591. #pragma mark - UIGestureRecognizerDelegate
  592. // 该方法返回的BOOL值决定了view是否能够同时响应多个手势
  593. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
  594. // NSLog(@"%@ - %@", gestureRecognizer.class, otherGestureRecognizer.class);
  595. return YES;
  596. }
  597. #pragma mark - SLZoomViewDelegate
  598. - (void)zoomViewDidEndMoveImage:(SLImageZoomView *)zoomView {
  599. self.drawView.lineWidth = 5.0/self.zoomView.zoomScale;
  600. self.mosaicView.squareWidth = 15/self.zoomView.zoomScale;
  601. self.mosaicView.paintSize = CGSizeMake(40/self.zoomView.zoomScale, 40/self.zoomView.zoomScale);
  602. }
  603. @end