TOCropOverlayView.m 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //
  2. // TOCropOverlayView.m
  3. //
  4. // Copyright 2015 Timothy Oliver. All rights reserved.
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to
  8. // deal in the Software without restriction, including without limitation the
  9. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. // sell copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
  21. // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. #import "TOCropOverlayView.h"
  23. static const CGFloat kTOCropOverLayerCornerWidth = 20.0f;
  24. @interface TOCropOverlayView ()
  25. @property (nonatomic, strong) NSArray *horizontalGridLines;
  26. @property (nonatomic, strong) NSArray *verticalGridLines;
  27. @property (nonatomic, strong) NSArray *outerLineViews; //top, right, bottom, left
  28. @property (nonatomic, strong) NSArray *topLeftLineViews; //vertical, horizontal
  29. @property (nonatomic, strong) NSArray *bottomLeftLineViews;
  30. @property (nonatomic, strong) NSArray *bottomRightLineViews;
  31. @property (nonatomic, strong) NSArray *topRightLineViews;
  32. - (void)setup;
  33. - (void)layoutLines;
  34. @end
  35. @implementation TOCropOverlayView
  36. - (instancetype)initWithFrame:(CGRect)frame
  37. {
  38. if (self = [super initWithFrame:frame]) {
  39. self.clipsToBounds = NO;
  40. [self setup];
  41. }
  42. return self;
  43. }
  44. - (void)setup
  45. {
  46. UIView *(^newLineView)(void) = ^UIView *(void){
  47. UIView *newLine = [[UIView alloc] initWithFrame:CGRectZero];
  48. newLine.backgroundColor = [UIColor whiteColor];
  49. [self addSubview:newLine];
  50. return newLine;
  51. };
  52. _outerLineViews = @[newLineView(), newLineView(), newLineView(), newLineView()];
  53. _topLeftLineViews = @[newLineView(), newLineView()];
  54. _bottomLeftLineViews = @[newLineView(), newLineView()];
  55. _topRightLineViews = @[newLineView(), newLineView()];
  56. _bottomRightLineViews = @[newLineView(), newLineView()];
  57. _horizontalGridLines = @[newLineView(), newLineView()];
  58. _verticalGridLines = @[newLineView(), newLineView()];
  59. }
  60. - (void)setFrame:(CGRect)frame
  61. {
  62. [super setFrame:frame];
  63. if (_outerLineViews)
  64. [self layoutLines];
  65. }
  66. - (void)didMoveToSuperview
  67. {
  68. [super didMoveToSuperview];
  69. if (_outerLineViews)
  70. [self layoutLines];
  71. }
  72. - (void)layoutLines
  73. {
  74. CGSize boundsSize = self.bounds.size;
  75. //border lines
  76. for (NSInteger i = 0; i < 4; i++) {
  77. UIView *lineView = self.outerLineViews[i];
  78. CGRect frame = CGRectZero;
  79. switch (i) {
  80. case 0: frame = (CGRect){0,-1.0f,boundsSize.width+2.0f, 1.0f}; break; //top
  81. case 1: frame = (CGRect){boundsSize.width,0.0f,1.0f,boundsSize.height}; break; //right
  82. case 2: frame = (CGRect){-1.0f,boundsSize.height,boundsSize.width+2.0f,1.0f}; break; //bottom
  83. case 3: frame = (CGRect){-1.0f,0,1.0f,boundsSize.height+1.0f}; break; //left
  84. }
  85. lineView.frame = frame;
  86. }
  87. //corner liness
  88. NSArray *cornerLines = @[self.topLeftLineViews, self.topRightLineViews, self.bottomRightLineViews, self.bottomLeftLineViews];
  89. for (NSInteger i = 0; i < 4; i++) {
  90. NSArray *cornerLine = cornerLines[i];
  91. CGRect verticalFrame, horizontalFrame;
  92. switch (i) {
  93. case 0: //top left
  94. verticalFrame = (CGRect){-3.0f,-3.0f,3.0f,kTOCropOverLayerCornerWidth+3.0f};
  95. horizontalFrame = (CGRect){0,-3.0f,kTOCropOverLayerCornerWidth,3.0f};
  96. break;
  97. case 1: //top right
  98. verticalFrame = (CGRect){boundsSize.width,-3.0f,3.0f,kTOCropOverLayerCornerWidth+3.0f};
  99. horizontalFrame = (CGRect){boundsSize.width-kTOCropOverLayerCornerWidth,-3.0f,kTOCropOverLayerCornerWidth,3.0f};
  100. break;
  101. case 2: //bottom right
  102. verticalFrame = (CGRect){boundsSize.width,boundsSize.height-kTOCropOverLayerCornerWidth,3.0f,kTOCropOverLayerCornerWidth+3.0f};
  103. horizontalFrame = (CGRect){boundsSize.width-kTOCropOverLayerCornerWidth,boundsSize.height,kTOCropOverLayerCornerWidth,3.0f};
  104. break;
  105. case 3: //bottom left
  106. verticalFrame = (CGRect){-3.0f,boundsSize.height-kTOCropOverLayerCornerWidth,3.0f,kTOCropOverLayerCornerWidth};
  107. horizontalFrame = (CGRect){-3.0f,boundsSize.height,kTOCropOverLayerCornerWidth+3.0f,3.0f};
  108. break;
  109. }
  110. [cornerLine[0] setFrame:verticalFrame];
  111. [cornerLine[1] setFrame:horizontalFrame];
  112. }
  113. //grid lines - horizontal
  114. CGFloat thickness = 1.0f / [[UIScreen mainScreen] scale];
  115. NSInteger numberOfLines = self.horizontalGridLines.count;
  116. CGFloat padding = (CGRectGetHeight(self.bounds) - (thickness*numberOfLines)) / (numberOfLines + 1);
  117. for (NSInteger i = 0; i < numberOfLines; i++) {
  118. UIView *lineView = self.horizontalGridLines[i];
  119. CGRect frame = CGRectZero;
  120. frame.size.height = thickness;
  121. frame.size.width = CGRectGetWidth(self.bounds);
  122. frame.origin.y = (padding * (i+1)) + (thickness * i);
  123. lineView.frame = frame;
  124. }
  125. //grid lines - vertical
  126. numberOfLines = self.verticalGridLines.count;
  127. padding = (CGRectGetWidth(self.bounds) - (thickness*numberOfLines)) / (numberOfLines + 1);
  128. for (NSInteger i = 0; i < numberOfLines; i++) {
  129. UIView *lineView = self.verticalGridLines[i];
  130. CGRect frame = CGRectZero;
  131. frame.size.width = thickness;
  132. frame.size.height = CGRectGetHeight(self.bounds);
  133. frame.origin.x = (padding * (i+1)) + (thickness * i);
  134. lineView.frame = frame;
  135. }
  136. }
  137. - (void)setGridHidden:(BOOL)hidden animated:(BOOL)animated
  138. {
  139. _gridHidden = hidden;
  140. if (animated == NO) {
  141. for (UIView *lineView in self.horizontalGridLines) {
  142. lineView.alpha = hidden ? 0.0f : 1.0f;
  143. }
  144. for (UIView *lineView in self.verticalGridLines) {
  145. lineView.alpha = hidden ? 0.0f : 1.0f;
  146. }
  147. return;
  148. }
  149. [UIView animateWithDuration:hidden?0.35f:0.2f animations:^{
  150. for (UIView *lineView in self.horizontalGridLines)
  151. lineView.alpha = hidden ? 0.0f : 1.0f;
  152. for (UIView *lineView in self.verticalGridLines)
  153. lineView.alpha = hidden ? 0.0f : 1.0f;
  154. }];
  155. }
  156. - (void)setGridHidden:(BOOL)gridHidden
  157. {
  158. [self setGridHidden:gridHidden animated:NO];
  159. }
  160. @end