SLEditMenuView.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. //
  2. // SLEditMenuView.m
  3. // DarkMode
  4. //
  5. // Created by wsl on 2019/10/9.
  6. // Copyright © 2019 wsl. All rights reserved.
  7. //
  8. #import "SLEditMenuView.h"
  9. #import "SLImageView.h"
  10. #import "SLImage.h"
  11. /// 涂鸦子菜单 画笔颜色选择
  12. @interface SLSubmenuGraffitiView : UIView
  13. @property (nonatomic, assign) int currentColorIndex; // 当前画笔颜色索引
  14. @property (nonatomic, strong) UIColor *currentColor; // 当前画笔颜色
  15. @property (nonatomic, copy) void(^selectedLineColor)(UIColor *lineColor); //选中颜色的回调
  16. @property (nonatomic, copy) void(^goBack)(void); //返回上一步
  17. @end
  18. @implementation SLSubmenuGraffitiView
  19. - (instancetype)initWithFrame:(CGRect)frame {
  20. self = [super initWithFrame:frame];
  21. if (self) {
  22. _currentColorIndex = 0;
  23. _currentColor = [UIColor whiteColor];
  24. }
  25. return self;
  26. }
  27. - (instancetype)init {
  28. self = [super init];
  29. if (self) {
  30. _currentColorIndex = 0;
  31. _currentColor = [UIColor whiteColor];
  32. }
  33. return self;
  34. }
  35. - (void)layoutSubviews {
  36. [super layoutSubviews];
  37. [self createSubmenu];
  38. }
  39. - (void)createSubmenu {
  40. for (UIView *subView in self.subviews) {
  41. [subView removeFromSuperview];
  42. }
  43. NSArray *colors = @[[UIColor whiteColor], [UIColor blackColor], [UIColor redColor], [UIColor yellowColor], [UIColor greenColor], [UIColor blueColor], [UIColor purpleColor], [UIColor clearColor]];
  44. int count = (int)colors.count;
  45. CGSize itemSize = CGSizeMake(20, 20);
  46. CGFloat space = (self.frame.size.width - count * itemSize.width)/(count + 1);
  47. for (int i = 0; i < count; i++) {
  48. UIButton * colorBtn = [[UIButton alloc] initWithFrame:CGRectMake(space + (itemSize.width + space)*i, (self.frame.size.height - itemSize.height)/2.0, itemSize.width, itemSize.height)];
  49. colorBtn.backgroundColor = colors[i];
  50. colorBtn.tag = 10 + i;
  51. [self addSubview:colorBtn];
  52. if (i == count - 1) {
  53. [colorBtn addTarget:self action:@selector(backToPreviousStep:) forControlEvents:UIControlEventTouchUpInside];
  54. [colorBtn setImage:[UIImage imageNamed:@"EditMenuGraffitiBack"] forState:UIControlStateNormal];
  55. }else {
  56. [colorBtn addTarget:self action:@selector(colorBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  57. colorBtn.layer.cornerRadius = itemSize.width/2.0;
  58. colorBtn.layer.borderColor = [UIColor whiteColor].CGColor;
  59. colorBtn.layer.borderWidth = 3;
  60. if (i != _currentColorIndex) {
  61. colorBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.8f, 0.8f);
  62. colorBtn.layer.borderWidth = 2;
  63. }else {
  64. colorBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0f, 1.0f);
  65. colorBtn.layer.borderWidth = 4;
  66. _currentColor = colors[i];
  67. self.selectedLineColor(colors[i]);
  68. }
  69. }
  70. }
  71. UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, self.frame.size.height - 1, self.frame.size.width, 0.5)];
  72. line.backgroundColor = [UIColor whiteColor];
  73. line.alpha = 0.5;
  74. [self addSubview:line];
  75. }
  76. // 选中当前画笔颜色
  77. - (void)colorBtnClicked:(UIButton *)colorBtn {
  78. UIButton *previousBtn = (UIButton *)[self viewWithTag:(10 + _currentColorIndex)];
  79. previousBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.8f, 0.8f);
  80. previousBtn.layer.borderWidth = 2;
  81. colorBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
  82. colorBtn.layer.borderWidth = 4;
  83. _currentColorIndex = (int)colorBtn.tag- 10;
  84. _currentColor = colorBtn.backgroundColor;
  85. self.selectedLineColor(colorBtn.backgroundColor);
  86. }
  87. //返回上一步
  88. - (void)backToPreviousStep:(id)sender {
  89. self.goBack();
  90. }
  91. @end
  92. //贴画CollectionViewCell
  93. @interface SLSubmenuStickingCell : UICollectionViewCell
  94. @property (nonatomic, strong) SLImageView *imageView;
  95. @end
  96. @implementation SLSubmenuStickingCell
  97. - (instancetype)initWithFrame:(CGRect)frame {
  98. self = [super initWithFrame:frame];
  99. if (self) {
  100. self.backgroundColor = [UIColor clearColor];
  101. [self setupUI];
  102. }
  103. return self;
  104. }
  105. - (void)setupUI {
  106. _imageView = [[SLImageView alloc] init];
  107. _imageView.contentMode = UIViewContentModeScaleAspectFit;
  108. [self.contentView addSubview:_imageView];
  109. }
  110. - (void)setImage:(NSString *)imageName {
  111. _imageView.frame = CGRectMake(0, 0, self.contentView.frame.size.width, self.contentView.frame.size.height);
  112. _imageView.image = [SLImage imageNamed:imageName];
  113. }
  114. @end
  115. /// 贴画子菜单
  116. @interface SLSubmenuStickingView : UIView <UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
  117. @property (nonatomic, strong) NSMutableArray *dataSource;
  118. @property (nonatomic, strong) UICollectionView *collectionView;
  119. @property (nonatomic, copy) void(^selectedImage)(SLImage *image); //选中的图片 贴画
  120. @end
  121. @implementation SLSubmenuStickingView
  122. - (instancetype)init {
  123. self = [super init];
  124. if (self) {
  125. }
  126. return self;
  127. }
  128. - (void)layoutSubviews {
  129. [super layoutSubviews];
  130. [self createSubmenu];
  131. }
  132. - (void)createSubmenu {
  133. [self addSubview:self.collectionView];
  134. }
  135. #pragma mark - Getter
  136. - (UICollectionView *)collectionView {
  137. if (_collectionView == nil) {
  138. UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
  139. layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
  140. _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) collectionViewLayout:layout];
  141. _collectionView.backgroundColor = [UIColor clearColor];
  142. _collectionView.delegate = self;
  143. _collectionView.dataSource = self;
  144. [_collectionView registerClass:[SLSubmenuStickingCell class] forCellWithReuseIdentifier:@"ItemId"];
  145. }
  146. return _collectionView;
  147. }
  148. - (NSMutableArray *)dataSource {
  149. if (_dataSource == nil) {
  150. _dataSource = [NSMutableArray array];
  151. for (int i = 0; i < 20; i++) {
  152. [_dataSource addObject:[NSString stringWithFormat:@"Resources.bundle/StickingImages/stickers_%d",i]];
  153. }
  154. }
  155. return _dataSource;
  156. }
  157. #pragma mark - UICollectionViewDelegate, UICollectionViewDataSource
  158. - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
  159. return 1;
  160. }
  161. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  162. return self.dataSource.count;
  163. }
  164. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  165. SLSubmenuStickingCell * item = [collectionView dequeueReusableCellWithReuseIdentifier:@"ItemId" forIndexPath:indexPath];
  166. [item setImage:self.dataSource[indexPath.row]];
  167. return item;
  168. }
  169. - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  170. [collectionView deselectItemAtIndexPath:indexPath animated:NO];
  171. self.selectedImage([SLImage imageNamed:self.dataSource[indexPath.row]]);
  172. }
  173. #pragma mark - UICollectionViewDelegateFlowLayout
  174. - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  175. return CGSizeMake((self.frame.size.width - 5*10)/4.0, self.frame.size.height);
  176. }
  177. //列间距
  178. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
  179. return 10;
  180. }
  181. //行间距
  182. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
  183. return 10;
  184. }
  185. - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
  186. return UIEdgeInsetsMake(0, 10, 0, 10);
  187. }
  188. @end
  189. /// 图片马赛克 子菜单 马赛克类型选择
  190. @interface SLSubmenuMosaicView : UIView
  191. @property (nonatomic, assign) NSInteger currentTypeIndex; //当前马赛克类型索引 默认0
  192. @property (nonatomic, copy) void(^goBack)(void); //返回上一步
  193. @property (nonatomic, copy) void(^selectedMosaicType)(NSInteger currentTypeIndex); // 选择马赛克类型 0:小方块 1:毛笔涂抹
  194. @end
  195. @implementation SLSubmenuMosaicView
  196. - (instancetype)initWithFrame:(CGRect)frame {
  197. self = [super initWithFrame:frame];
  198. if (self) {
  199. }
  200. return self;
  201. }
  202. - (instancetype)init {
  203. self = [super init];
  204. if (self) {
  205. }
  206. return self;
  207. }
  208. - (void)layoutSubviews {
  209. [super layoutSubviews];
  210. [self createSubmenu];
  211. }
  212. - (void)createSubmenu {
  213. for (UIView *subView in self.subviews) {
  214. [subView removeFromSuperview];
  215. }
  216. NSArray *imageNames = @[@"EditMenuMosaic", @"EditBrushMosaic", @"EditMenuGraffitiBack"];
  217. NSArray *imageNamesSelected = @[@"EditMenuMosaicSelected", @"EditBrushMosaicSelected", @"EditMenuGraffitiBack"];
  218. int count = (int)imageNames.count;
  219. CGSize itemSize = CGSizeMake(50, 50);
  220. CGFloat space = (self.frame.size.width - count * itemSize.width)/(count + 1);
  221. for (int i = 0; i < count; i++) {
  222. UIButton * colorBtn = [[UIButton alloc] initWithFrame:CGRectMake(space + (itemSize.width + space)*i, (self.frame.size.height - itemSize.height)/2.0, itemSize.width, itemSize.height)];
  223. colorBtn.tag = 10 + i;
  224. [self addSubview:colorBtn];
  225. if (i == count - 1) {
  226. [colorBtn addTarget:self action:@selector(backToPreviousStep:) forControlEvents:UIControlEventTouchUpInside];
  227. }else {
  228. [colorBtn addTarget:self action:@selector(mosaicTypeBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  229. }
  230. if(i == _currentTypeIndex) {
  231. colorBtn.selected = YES;
  232. }
  233. [colorBtn setImage:[UIImage imageNamed:imageNames[i]] forState:UIControlStateNormal];
  234. [colorBtn setImage:[UIImage imageNamed:imageNamesSelected[i]] forState:UIControlStateSelected];
  235. }
  236. UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, self.frame.size.height - 1, self.frame.size.width, 0.5)];
  237. line.backgroundColor = [UIColor whiteColor];
  238. line.alpha = 0.5;
  239. [self addSubview:line];
  240. }
  241. - (void)backToPreviousStep:(id)sender {
  242. self.goBack();
  243. }
  244. //马赛克类型
  245. - (void)mosaicTypeBtnClicked:(UIButton *)btn {
  246. btn.selected = !btn.selected;
  247. UIButton *currentView = [self viewWithTag:(_currentTypeIndex + 10)];
  248. currentView.selected = !currentView.selected;
  249. _currentTypeIndex = btn.tag - 10;
  250. self.selectedMosaicType(_currentTypeIndex);
  251. }
  252. @end
  253. /// 编辑主菜单
  254. @interface SLEditMenuView ()
  255. @property (nonatomic, strong) NSArray *menuTypes; //编辑类型集合
  256. @property (nonatomic, strong) NSArray *imageNames; //编辑图标名称
  257. @property (nonatomic, strong) NSArray *imageNamesSelected; //选中的 编辑图标名称
  258. @property (nonatomic, strong) NSMutableArray *menuBtns; //编辑菜单按钮集合
  259. @property (nonatomic, strong) UIView *currentSubmenu; //当前显示的子菜单
  260. @property (nonatomic, strong) SLSubmenuGraffitiView *submenuGraffiti; //涂鸦子菜单
  261. @property (nonatomic, strong) SLSubmenuStickingView *submenuSticking; //贴图子菜单
  262. @property (nonatomic, strong) SLSubmenuMosaicView *submenuMosaic; //图片马赛克
  263. @end
  264. @implementation SLEditMenuView
  265. #pragma mark - Override
  266. - (instancetype)initWithFrame:(CGRect)frame {
  267. self = [super initWithFrame:frame];
  268. if (self) {
  269. }
  270. return self;
  271. }
  272. #pragma mark - UI
  273. - (void)createEditMenus {
  274. for (UIView *subView in self.subviews) {
  275. if (subView == _submenuGraffiti || subView == _submenuSticking || subView == _submenuMosaic) {
  276. continue;
  277. }
  278. [subView removeFromSuperview];
  279. }
  280. int count = (int)_menuTypes.count;
  281. CGSize itemSize = CGSizeMake(20, 20);
  282. CGFloat space = (self.frame.size.width - count * itemSize.width)/count;
  283. _menuBtns = [NSMutableArray array];
  284. for (int i = 0; i < count; i++) {
  285. UIButton * menuBtn = [[UIButton alloc] initWithFrame:CGRectMake(space/2.0 + (itemSize.width + space)*i, self.frame.size.height - 80, itemSize.width, 80)];
  286. menuBtn.tag = [_menuTypes[i] intValue];
  287. [menuBtn setImage:[UIImage imageNamed:_imageNames[i]] forState:UIControlStateNormal];
  288. [menuBtn setImage:[UIImage imageNamed:_imageNamesSelected[i]] forState:UIControlStateSelected];
  289. [menuBtn addTarget:self action:@selector(menuBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  290. [self addSubview:menuBtn];
  291. [_menuBtns addObject:menuBtn];
  292. }
  293. }
  294. - (void)setEditObject:(SLEditObject)editObject {
  295. _editObject = editObject;
  296. if (editObject == SLEditObjectPicture) {
  297. _menuTypes = @[@(SLEditMenuTypeGraffiti), @(SLEditMenuTypeSticking), @(SLEditMenuTypeText),@(SLEditMenuTypePictureMosaic), @(SLEditMenuTypePictureClipping)];
  298. _imageNames = @[@"EditMenuGraffiti", @"EditMenuSticker", @"EditMenuText", @"EditMenuMosaic", @"EditMenuClipImage"];
  299. _imageNamesSelected = @[@"EditMenuGraffitiSelected", @"EditMenuStickerSelected", @"EditMenuText",@"EditMenuMosaicSelected",@"EditMenuClipImage"];
  300. }else if (editObject == SLEditObjectVideo) {
  301. _menuTypes = @[@(SLEditMenuTypeGraffiti), @(SLEditMenuTypeSticking), @(SLEditMenuTypeText), @(SLEditMenuTypeVideoClipping)];
  302. _imageNames = @[@"EditMenuGraffiti", @"EditMenuSticker", @"EditMenuText", @"EditMenuCut"];
  303. _imageNamesSelected = @[@"EditMenuGraffitiSelected", @"EditMenuStickerSelected", @"EditMenuText", @"EditMenuCut"];
  304. }
  305. [self createEditMenus];
  306. }
  307. #pragma mark - Getter
  308. - (SLSubmenuGraffitiView *)submenuGraffiti {
  309. if (!_submenuGraffiti) {
  310. _submenuGraffiti = [[SLSubmenuGraffitiView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 60)];
  311. _submenuGraffiti.hidden = YES;
  312. __weak typeof(self) weakSelf = self;
  313. _submenuGraffiti.selectedLineColor = ^(UIColor *lineColor) {
  314. weakSelf.selectEditMenu(SLEditMenuTypeGraffiti, @{@"lineColor":lineColor});
  315. };
  316. _submenuGraffiti.goBack = ^{
  317. weakSelf.selectEditMenu(SLEditMenuTypeGraffiti, @{@"goBack":@(YES)});
  318. };
  319. }
  320. return _submenuGraffiti;
  321. }
  322. - (SLSubmenuStickingView *)submenuSticking {
  323. if (!_submenuSticking) {
  324. _submenuSticking = [[SLSubmenuStickingView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 60)];
  325. _submenuSticking.hidden = YES;
  326. __weak typeof(self) weakSelf = self;
  327. _submenuSticking.selectedImage = ^(SLImage *image) {
  328. weakSelf.selectEditMenu(SLEditMenuTypeSticking, @{@"image":image});
  329. };
  330. }
  331. return _submenuSticking;
  332. }
  333. - (SLSubmenuMosaicView *)submenuMosaic {
  334. if (!_submenuMosaic) {
  335. _submenuMosaic = [[SLSubmenuMosaicView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 60)];
  336. _submenuMosaic.hidden = YES;
  337. __weak typeof(self) weakSelf = self;
  338. _submenuMosaic.selectedMosaicType = ^(NSInteger currentTypeIndex) {
  339. weakSelf.selectEditMenu(SLEditMenuTypePictureMosaic, @{@"mosaicType":@(currentTypeIndex)});
  340. };
  341. _submenuMosaic.goBack = ^{
  342. weakSelf.selectEditMenu(SLEditMenuTypePictureMosaic, @{@"goBack":@(YES)});
  343. };
  344. }
  345. return _submenuMosaic;
  346. }
  347. #pragma mark - Evenst Handle
  348. - (void)menuBtnClicked:(UIButton *)menuBtn {
  349. for (UIButton *subView in self.menuBtns) {
  350. if (subView == menuBtn) {
  351. subView.selected = !subView.selected;
  352. } else {
  353. subView.selected = NO;
  354. }
  355. }
  356. SLEditMenuType editMenuType = menuBtn.tag;
  357. switch (editMenuType) {
  358. case SLEditMenuTypeGraffiti:
  359. [self hiddenView:self.submenuGraffiti];
  360. self.selectEditMenu(editMenuType, @{@"hidden":@(self.submenuGraffiti.hidden), @"lineColor": self.submenuGraffiti.currentColor});
  361. break;
  362. case SLEditMenuTypeSticking:
  363. [self hiddenView:self.submenuSticking];
  364. self.selectEditMenu(editMenuType, @{@"hidden":@(self.submenuSticking.hidden)});
  365. break;
  366. case SLEditMenuTypeText:
  367. [self hiddenView:self.currentSubmenu hidden:YES];
  368. self.selectEditMenu(editMenuType, @{@"hidden":@(self.submenuSticking.hidden)});
  369. break;
  370. case SLEditMenuTypeVideoClipping:
  371. [self hiddenView:self.currentSubmenu hidden:YES];
  372. self.selectEditMenu(editMenuType, nil);
  373. break;
  374. case SLEditMenuTypePictureMosaic:
  375. [self hiddenView:self.submenuMosaic];
  376. self.selectEditMenu(editMenuType, @{@"hidden":@(self.submenuMosaic.hidden), @"mosaicType":@(self.submenuMosaic.currentTypeIndex)});
  377. break;
  378. case SLEditMenuTypePictureClipping:
  379. [self hiddenView:self.currentSubmenu hidden:YES];
  380. self.selectEditMenu(editMenuType, @{@"hidden":@(NO)});
  381. break;
  382. default:
  383. break;
  384. }
  385. }
  386. #pragma mark - Help Methods
  387. - (void)hiddenView:(UIView *)view {
  388. if (self.currentSubmenu == view || self.currentSubmenu == nil) {
  389. [self hiddenView:view hidden:!view.hidden];
  390. }else {
  391. [self hiddenView:self.currentSubmenu hidden:YES];
  392. [self hiddenView:view hidden:NO];
  393. }
  394. }
  395. - (void)hiddenView:(UIView *)view hidden:(BOOL)hidden{
  396. if(view == nil || view.hidden == hidden) return;
  397. if (hidden) {
  398. view.hidden = YES;
  399. [view removeFromSuperview];
  400. }else {
  401. view.hidden = NO;
  402. self.currentSubmenu = view;
  403. [self addSubview:view];
  404. }
  405. }
  406. @end