【发布时间】:2015-01-05 14:50:24
【问题描述】:
通过this question and answer,我现在有了一种有效的方法来检测任意旋转的图像何时不完全位于裁剪区域之外。
下一步是弄清楚如何正确调整它包含滚动视图缩放,以确保裁剪矩形内没有空格。为了澄清,我想放大(放大)图像;裁剪矩形应保持未转换。
布局层次如下所示:
containing UIScrollView
UIImageView (this gets arbitrarily rotated)
crop rect overlay view
... UIImageView 也可以在 scrollView 内进行缩放和平移。
需要考虑发生的 4 个手势事件:
- 平移手势(完成):通过检测是否平移错误并重置 contentOffset 来完成。
- 旋转 CGAffineTransform
- 滚动视图缩放
- 裁剪矩形覆盖框的调整
据我所知,我应该能够对 2、3 和 4 使用相同的逻辑来调整滚动视图的 zoomScale 以使图像适合。
如何正确计算使旋转后的图像完全适合裁剪区域所需的缩放比例?
为了更好地说明我想要完成的工作,这里是一个不正确大小的示例:
我需要计算使其看起来像这样所需的缩放比例:
这是我到目前为止使用 Oluseyi 的解决方案获得的代码。它在旋转角度较小(例如小于 1 弧度)时有效,但任何超过此值的情况都会变得非常不稳定。
CGRect visibleRect = [_scrollView convertRect:_scrollView.bounds toView:_imageView];
CGRect cropRect = _cropRectView.frame;
CGFloat rotationAngle = fabs(self.rotationAngle);
CGFloat a = visibleRect.size.height * sinf(rotationAngle);
CGFloat b = visibleRect.size.width * cosf(rotationAngle);
CGFloat c = visibleRect.size.height * cosf(rotationAngle);
CGFloat d = visibleRect.size.width * sinf(rotationAngle);
CGFloat zoomDiff = MAX(cropRect.size.width / (a + b), cropRect.size.height / (c + d));
CGFloat newZoomScale = (zoomDiff > 1) ? zoomDiff : 1.0 / zoomDiff;
[UIView animateWithDuration:0.2
delay:0.05
options:NO
animations:^{
[self centerToCropRect:[self convertRect:cropRect toView:self.zoomingView]];
_scrollView.zoomScale = _scrollView.zoomScale * newZoomScale;
} completion:^(BOOL finished) {
if (![self rotatedView:_imageView containsViewCompletely:_cropRectView])
{
// Damn, it's still broken - this happens a lot
}
else
{
// Woo! Fixed
}
_didDetectBadRotation = NO;
}];
请注意,我正在使用 AutoLayout,这会使框架和边界变得愚蠢。
【问题讨论】:
-
image view 是只绕中心旋转,还是可以平移?
-
@robmayoff 它也可以被翻译,但如果我能让它基于中心旋转工作,那将是一个巨大的开始。然后我可以使用相同的计算来比较裁剪视图的中心或其他东西。
-
对于其他查看赏金的人来说,Oluseyi 下面的回答肯定是部分有效,但并非完全有效。随意添加其他答案。
-
你找到方法了吗?
-
@brandonscript 你有想过这个吗?
标签: ios objective-c uiscrollview cgaffinetransform