这篇文章就是介绍开篇说的图片裁剪视图的构建。
效果图如上图所示. 要求:
首先, 初步分析需求. 缩放操作可以利用ScollView的Zoom属性来实现. 旋转可以利用UIView的TransForm来实现. 感觉很简单. 确实.
但是, 怎么拼合这3个视图的关系, 才能在进行缩放, 拖动的时候知道选择区与ImageView的相对坐标呢? 以此我们通过DrawInRect函数正确输出选择的图片?
View Hierarchy:
经过一番分析和实验, (这里忽略了如何解决这个问题的过程, 因为写起来很复杂.)最终可以实现的方法如下:
以上这样做的好处就是, 直接利用ScrollView的ContentOffset属性就可以轻易的知道选择区在图片上的相对位置. 如下.
CGRectMake(-_scrollView.contentOffset.x, -_scrollView.contentOffset.y, _scrollView.contentSize.width, _scrollView.contentSize.height);
整个裁剪的代码:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(320, 320), 1, 1); CGRect drawRect = CGRectMake(-_scrollView.contentOffset.x, -_scrollView.contentOffset.y, _scrollView.contentSize.width, _scrollView.contentSize.height); [origionImage drawInRect:drawRect]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
一目了然, 相当简便, 省去了诸多宽高的反复计算. 也不用来回倒腾UIImageView和ScrollView的几何属性.
对于需求2的旋转操作. 每当进行一次旋转的时候, 我们只是让ScrollView(而不是ImageView)进行旋转, 如下:
- (void)rotateClockWise90Degree { _rotateCounter++; [_scrollView setZoomScale:1.f]; CGAffineTransform rotateTranform = CGAffineTransformRotate(_scrollView.transform, M_PI_2); [UIView animateWithDuration:.25f animations:^{ _scrollView.transform = rotateTranform; }]; }
旋转后的裁剪, 我们依然使用前面的裁剪代码. 这样裁剪的坐标系始终是ScrollView的坐标系. 然后我们图像做一次旋转, 这里有个技巧, 我们不需设置绘制Context的Transfrom, 并对Image进行重新DrawRect. 我们可以调用系统的一个函数, 一段语句完成这个操作, 如下.
image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:orientation];
非常简单. 当然orientation参数是通过旋转次数计算出来的.
这样所有的操作最终简练成2段语句
CGRect drawRect = CGRectMake(-_scrollView.contentOffset.x, -_scrollView.contentOffset.y, _scrollView.contentSize.width, _scrollView.contentSize.height);
与
image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:orientation];
所以, 只要提前设计好了需求的实现, 代码写起来也是想当的方便易懂.
代码下载地址: DownLoad