如何在UIScrollView中启用缩放

63

如何启用 UIScrollView 中的缩放功能?

4个回答

209
答案在这里

滚动视图(UIScrollView)还处理内容的缩放和拖动。当用户进行捏合手势时,滚动视图会调整内容的偏移量和缩放比例。手势结束时,管理内容视图的对象应根据需要更新内容的子视图。(请注意,手势可以结束但某个手指仍然按下。)在手势进行中,滚动视图不会向子视图发送任何跟踪调用。

UIScrollView类可以有一个必须采用UIScrollViewDelegate协议的委托。为了使缩放和拖动功能正常工作,必须实现委托方法:viewForZoomingInScrollView: 和 scrollViewDidEndZooming:withView:atScale:。此外,最大(maximumZoomScale)和最小(minimumZoomScale)缩放比例必须不同。

所以:
  1. 你需要一个实现UIScrollViewDelegate协议并设置为你的UIScrollView实例的delegate的委托对象。
  2. 在你的委托对象上,你必须实现一个方法:viewForZoomingInScrollView:该方法必须返回你要缩放的内容视图)。你也可以选择性地实现scrollViewDidEndZooming:withView:atScale:方法。
  3. 在你的UIScrollView实例上,你必须将minimumZoomScalemaximumZoomScale设置为不同的值(默认值为1.0)。
注意:有趣的是如果你想要禁用缩放,那么仅仅在viewForZooming...方法中返回nil是否就足够了呢?虽然这确实可以禁用缩放,但是某些手势(对于两个手指)可能会出现问题。因此,为了禁用缩放,你应该将最小和最大缩放比例都设置为1.0。

18
非常好的答案——这正好给了我所需的内容。(另外,我也不用去看视频了!;)) - Olie
1
感谢。这里最重要的是第二步,原始答案中没有找到。 - thgc
1
这应该被标记为真正的答案! - Chris
1
还有一个非常好的教程在 http://www.appcoda.com/uiscrollview-introduction/ 上,描述了如何通过编程设置最小和最大缩放级别,通过轻触进行缩放等。 - Jan Molak
我不明白为什么这些控件没有所有功能。 - Duck

9
请阅读一下这篇 Ray Wenderlich 的教程:
http://www.raywenderlich.com/76436/use-uiscrollview-scroll-zoom-content-swift
如果您按照“滚动和缩放较大的图像”部分进行操作,它将呈现出一张图片,并启用您捏合和缩放图片的功能。
如果链接发生更改,以下是主要信息:将此代码放入您的视图控制器中(这将设置主要功能):
override func viewDidLoad() {
  super.viewDidLoad()

  // 1
  let image = UIImage(named: "photo1.png")!
  imageView = UIImageView(image: image)
  imageView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size:image.size)
  scrollView.addSubview(imageView)

  // 2
  scrollView.contentSize = image.size

  // 3
  var doubleTapRecognizer = UITapGestureRecognizer(target: self, action: "scrollViewDoubleTapped:")
  doubleTapRecognizer.numberOfTapsRequired = 2
  doubleTapRecognizer.numberOfTouchesRequired = 1
  scrollView.addGestureRecognizer(doubleTapRecognizer)

  // 4
  let scrollViewFrame = scrollView.frame
  let scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
  let scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
  let minScale = min(scaleWidth, scaleHeight);
  scrollView.minimumZoomScale = minScale;

  // 5
  scrollView.maximumZoomScale = 1.0
  scrollView.zoomScale = minScale;

  // 6
  centerScrollViewContents()
}

将以下内容添加到类中:
func centerScrollViewContents() {
  let boundsSize = scrollView.bounds.size
  var contentsFrame = imageView.frame

  if contentsFrame.size.width < boundsSize.width {
    contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0
  } else {
    contentsFrame.origin.x = 0.0
  }

  if contentsFrame.size.height < boundsSize.height {
    contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0
  } else {
    contentsFrame.origin.y = 0.0
  }

  imageView.frame = contentsFrame
}

如果您想要识别双击手势,请按照以下步骤进行操作:
func scrollViewDoubleTapped(recognizer: UITapGestureRecognizer) {
  // 1        
  let pointInView = recognizer.locationInView(imageView)

  // 2
  var newZoomScale = scrollView.zoomScale * 1.5
  newZoomScale = min(newZoomScale, scrollView.maximumZoomScale)

  // 3
  let scrollViewSize = scrollView.bounds.size
  let w = scrollViewSize.width / newZoomScale
  let h = scrollViewSize.height / newZoomScale
  let x = pointInView.x - (w / 2.0)
  let y = pointInView.y - (h / 2.0)

  let rectToZoomTo = CGRectMake(x, y, w, h);

  // 4
  scrollView.zoomToRect(rectToZoomTo, animated: true)
}

如果您想了解更多细节,请阅读教程,但基本上这就是它的全部内容。

1
虽然这可能是一个相当好的答案,但它本质上是一个“仅链接”的答案。您应该从链接中包含一些信息,以便如果链接后面的信息发生变化/丢失,答案仍然有意义。请参见此链接 - James Webster

5

请确保您将viewController设置为scrollViews的代理并实现以下方法:

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return imageView
}

0

不需要设置滚动视图的内容大小,上述解决方案在Xcode 4.3+和iOS 5.0上都可以完美运行。 - Deepak
1
虽然这可能是一个相当不错的答案,但它本质上是一个“仅链接”答案。您应该包含一些来自您链接的信息,以便如果链接背后的信息发生了变化/丢失,答案仍然有意义。参见此链接 - James Webster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接