如何限制将捏缩放图像移动到图像边框?
Posted
技术标签:
【中文标题】如何限制将捏缩放图像移动到图像边框?【英文标题】:How to restrict shifting of a pinch zoomed image to the image borders? 【发布时间】:2015-11-17 14:35:10 【问题描述】:我在情节提要中设置了一个scrollView
,其中包含一个imageView
,使用自动布局,如图所示here。
此外,我为此imageView
启用了捏缩放,如docs 中所述。
imageView
在scollView
的两侧有 4 个 0 约束,并且它与主视图具有相等的宽度和高度,主视图具有 scrollView
作为子视图。
imageView
具有aspectFit
缩放模式,因此在未缩放状态下,图像将完全从左到右或从上到下(或两者)延伸。
在下面的示例中,它从上到下延伸,使一些背景左右可见:
我可以捏缩放图像,使其比屏幕大:
我可以向上或向下移动缩放的图像,但在顶部或底部的背景变得可见之前移动停止。这是我想要的。
但是,我可以将缩放后的图像向左或向右移动,以便可以看到背景:
我怎样才能避免将图像移动这么远(这里,向右)。与顶部或底部一样,它应该在边界处停止移动,这样就看不到背景了。
【问题讨论】:
【参考方案1】:不是理想的解决方案,但我希望它会有所帮助:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
[self adjustScrollViewInsets];
- (void)adjustScrollViewInsets
CGFloat imageWidth = self.imageView.image.size.width;
CGFloat imageHeight = self.imageView.image.size.height;
CGFloat aspect = imageWidth / imageHeight;
CGSize imageViewSize = self.imageView.frame.size;
if (imageViewSize.width / aspect <= imageViewSize.height)
[self adjustVerticalInsetsWithImageHeight:(imageViewSize.width / aspect)];
else
[self adjustHorizontalInsetsWithImageWidth:(imageViewSize.height * aspect)];
- (void)adjustHorizontalInsetsWithImageWidth:(CGFloat)width
CGFloat horizontalInset = (self.scrollView.contentSize.width - width) / 2;
if (width < self.scrollView.frame.size.width)
horizontalInset = horizontalInset - (self.scrollView.frame.size.width - width) / 2;
[self.scrollView setContentInset:UIEdgeInsetsMake(0, -horizontalInset, 0, -horizontalInset)];
- (void)adjustVerticalInsetsWithImageHeight:(CGFloat)height
CGFloat verticalInset = (self.scrollView.contentSize.height - height) / 2;
if (height < self.scrollView.frame.size.height)
verticalInset = verticalInset - (self.scrollView.frame.size.height - height) / 2;
[self.scrollView setContentInset:UIEdgeInsetsMake(-verticalInset, 0, -verticalInset, 0)];
如果您遇到问题,请查看this repo。
【讨论】:
嗨弗拉基米尔,我测试了你的代码。它正确计算插入。奇怪的是,使用正确的参数应用 setContentInset: 后,1)显示没有改变,即图像的大小没有改变并且周围的背景(如果有的话)仍然可见,2)它不再可以在应用插入的方向滚动(如果原始图像是横向的,即高度 您好弗拉基米尔,我发现了问题:您的代码没有考虑缩放比例因子。如果,例如垂直插入被设置,它们被设置为可见区域,并且即使缩放的图像允许垂直滚动也不可能。为了纠正这个问题,必须将 adjustVerticalInsetsWithImageHeight: 的参数与 scrollView.zoomScale 相乘(水平类似)。如果您同意,请编辑您的答案,我会接受。 我无法重现您的滚动问题(使用模拟器测试,9.1)。您是从我的存储库还是您自己的实现中测试了一个项目?无需考虑缩放比例因子,因为内容的大小和图像视图的大小已经针对当前比例进行了计算。您能否提供有关滚动问题的更多信息?视频或示例项目会很有帮助。 我用自己的实现进行了尝试。我会尽快提供更多信息。 我在代码中发现了问题:在您的代码中,scrollView 将 imageView 作为子视图。当 scrollView 被缩放时,imageView 也被缩放,并且不需要像您的代码中那样额外的缩放因子。在我的代码中,scrollView 有一个intermediateView 作为子视图,intermediateView 有一个imageView 作为子视图。当 scrollView 被缩放时,intermediateView 也被缩放,而 imageView 没有被缩放。因此,adjustVerticalInsetsWithImageHeight:(imageViewSize.width / aspect)*zoomscale 和 adjustVerticalInsetsWithImageHeight:(intermediateViewSize.width / aspect) 都有效。再次感谢您的回答!【参考方案2】:我遇到了同样的问题,并在 Swift 4.0 中实现,如下所示,它对我有用。
Swift 4.0:
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat)
adjustScrollViewInsets()
func adjustScrollViewInsets()
let imageWidth = self.imageView.image?.size.width
let imageHeight = self.imageView.image?.size.height
let aspect = imageWidth! / imageHeight!
let imageViewSize = self.imageView.frame.size
if imageViewSize.width / aspect <= imageViewSize.height
adjustVerticalInsetsWithImageHeight(height: imageViewSize.width / 2)
else
adjustHorizontalInsetsWithImageWidth(width: imageViewSize.height / 2)
func adjustHorizontalInsetsWithImageWidth(width: CGFloat)
var horizontalInset = (self.scrollView.contentSize.width - width) / 2
if width < self.scrollView.contentSize.width
horizontalInset = horizontalInset - (self.scrollView.frame.size.width - width) / 2
self.scrollView.contentInset = UIEdgeInsetsMake(0, -horizontalInset, 0, -horizontalInset)
func adjustVerticalInsetsWithImageHeight(height: CGFloat)
var verticalInset = (self.scrollView.contentSize.height - height) / 2
if height < self.scrollView.frame.size.height
verticalInset = verticalInset - (self.scrollView.frame.size.height - height) / 2
self.scrollView.contentInset = UIEdgeInsetsMake(-verticalInset, 0, -verticalInset, 0)
【讨论】:
虽然此答案可能是正确且有用的,但如果您 include some explanation along with it 解释它如何帮助解决问题,则最好。如果有更改(可能不相关)导致它停止工作并且用户需要了解它曾经是如何工作的,这在未来变得特别有用。以上是关于如何限制将捏缩放图像移动到图像边框?的主要内容,如果未能解决你的问题,请参考以下文章