// // FKPhotoClipView.m // FirstLink // // Created by ascii on 16/6/13. // Copyright © 2016年 FirstLink. All rights reserved. // #import "FKPhotoClipView.h" @implementation FKPhotoClipGridView - (id)init { self = [super init]; if (self) { [self configInitData]; self.layer.borderWidth = self.width; self.layer.borderColor = self.color.CGColor; } return self; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self configInitData]; } return self; } - (void)configInitData { self.color = [UIColor whiteColor]; self.width = 1; self.row = 2; self.column = 2; } - (void)drawRect:(CGRect)rect { [super drawRect:rect]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, self.color.CGColor); CGContextSetLineWidth(context, self.width); // draw row line int distance = (int)(CGRectGetHeight(self.frame)/((float)(self.row + 1))); for (int idx = 0; idx < self.row; idx++) { CGContextMoveToPoint(context, 0.0f, distance*(idx+1)); CGContextAddLineToPoint(context, CGRectGetWidth(self.frame), distance*(idx+1)); } // draw column line distance = (int)(CGRectGetWidth(self.frame)/((float)(self.column + 1))); for (int idx = 0; idx < self.column; idx++) { CGContextMoveToPoint(context, distance*(idx+1), 0.0f); CGContextAddLineToPoint(context, distance*(idx+1), CGRectGetHeight(self.frame)); } CGContextStrokePath(context); } @end #pragma mark - FKPhotoClipView @interface FKPhotoClipView () @property (nonatomic, strong) UIImage *sourceImage; @property (nonatomic, strong) UIScrollView *scrollView; @property (nonatomic, strong) UIImageView *imageView; @property (nonatomic, strong) FKPhotoClipGridView *gridView; @end @implementation FKPhotoClipView /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ - (instancetype)initWithImage:(UIImage *)image { self = [super init]; if (self) { [self setImage:image]; self.clipsToBounds = YES; [self addSubview:self.scrollView]; [self.scrollView addSubview:self.imageView]; [self addSubview:self.gridView]; } return self; } - (void)setImage:(UIImage *)image { _sourceImage = [image copy]; self.imageView.image = _sourceImage; } - (UIImage *)getClipImage { CGRect rectInImageView = CGRectMake(self.scrollView.contentOffset.x , self.scrollView.contentOffset.y , CGRectGetWidth(self.gridView.frame) , CGRectGetHeight(self.gridView.frame)); CGFloat scale = CGRectGetWidth(self.imageView.frame)/self.sourceImage.size.width; CGRect rectInImage = CGRectMake((int)(CGRectGetMinX(rectInImageView)/scale) , (int)(CGRectGetMinY(rectInImageView)/scale) , (int)(CGRectGetWidth(rectInImageView)/scale) , (int)(CGRectGetHeight(rectInImageView)/scale)); CGImageRef suourceImageRef = CGImageCreateWithImageInRect(self.sourceImage.CGImage, rectInImage); CGRect subBounds = CGRectMake(0, 0, CGImageGetWidth(suourceImageRef), CGImageGetHeight(suourceImageRef)); UIGraphicsBeginImageContext(subBounds.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextDrawImage(context, subBounds, suourceImageRef); UIImage* subImage = [UIImage imageWithCGImage:suourceImageRef]; UIGraphicsEndImageContext(); return subImage; } - (void)drawRect:(CGRect)rect { [super drawRect:rect]; if (self.sourceImage) { self.gridView.frame = self.bounds; self.scrollView.frame = self.bounds; [self setVisableViewContentSize:[self minVisableViewSize]]; [self setVisableViewCenterAnimated:NO]; } } #pragma mark - Method - (CGSize)minVisableViewSize { CGFloat length = CGRectGetWidth(self.frame); CGFloat width = self.sourceImage.size.width; CGFloat height = self.sourceImage.size.height; CGFloat minSide = MIN(width, height); return CGSizeMake(ceilf(width*length/minSide), ceilf(height*length/minSide)); } - (void)setVisableViewContentSize:(CGSize)size { // +1是为了保证scrollView可滑动 self.scrollView.contentSize = size; self.imageView.frame = CGRectMake(0, 0, size.width + 1, size.height + 1); } - (void)scaleVisableViewToMinSize:(CGSize)size { CGSize minSize = [self minVisableViewSize]; if (size.width < minSize.width || size.height < minSize.height) { __weak FKPhotoClipView *weakSelf = self; [UIView animateWithDuration:0.3 animations:^ { // +1是为了保证scrollView可滑动 weakSelf.scrollView.contentSize = minSize; weakSelf.imageView.frame = CGRectMake(0, 0, minSize.width + 1, minSize.height + 1); } completion:^(BOOL finished) { [weakSelf setVisableViewCenterAnimated:NO]; }]; } } - (void)setVisableViewCenterAnimated:(BOOL)animated { CGFloat centerOffsetX = (self.scrollView.contentSize.width/2) - (self.scrollView.bounds.size.width/2); CGFloat centerOffsetY = (self.scrollView.contentSize.height/2) - (self.scrollView.bounds.size.width/2); [self.scrollView setContentOffset:CGPointMake(centerOffsetX, centerOffsetY) animated:animated]; } - (void)setVisableViewContentOffsetScale:(CGFloat)scale { CGFloat centerOffsetX = (self.scrollView.contentOffset.x*scale); CGFloat centerOffsetY = (self.scrollView.contentOffset.y*scale); [self.scrollView setContentOffset:CGPointMake(centerOffsetX, centerOffsetY) animated:NO]; } #pragma mark - Action - (void)pinchViewGesture:(UIPinchGestureRecognizer *)pinchGestureRecognizer { if (pinchGestureRecognizer.state == UIGestureRecognizerStateBegan || pinchGestureRecognizer.state == UIGestureRecognizerStateChanged || pinchGestureRecognizer.state == UIGestureRecognizerStateEnded) { UIView *view = self.imageView; CGFloat scale = pinchGestureRecognizer.scale; view.transform = CGAffineTransformScale(view.transform, scale, scale); pinchGestureRecognizer.scale = 1; if (pinchGestureRecognizer.state == UIGestureRecognizerStateEnded) { [self scaleVisableViewToMinSize:view.frame.size]; } else { [self setVisableViewContentSize:view.frame.size]; [self setVisableViewContentOffsetScale:scale]; } } } #pragma mark - Property - (UIScrollView *)scrollView{ if (!_scrollView) { _scrollView = [[UIScrollView alloc] init]; _scrollView.backgroundColor = [UIColor blackColor]; _scrollView.showsHorizontalScrollIndicator = NO; _scrollView.showsVerticalScrollIndicator = NO; } return _scrollView; } - (UIImageView *)imageView { if (!_imageView) { _imageView = [UIImageView new]; _imageView.userInteractionEnabled = YES; UIPinchGestureRecognizer *gesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchViewGesture:)]; [_imageView addGestureRecognizer:gesture]; } return _imageView; } - (FKPhotoClipGridView *)gridView { if (!_gridView) { _gridView = [FKPhotoClipGridView new]; _gridView.userInteractionEnabled = NO; _gridView.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; } return _gridView; } @end