UIImageView捏缩放迅速


70

我希望有人可以帮助我。我试图允许用户捏UIImageView(允许最大和最小级别)上的缩放。但是由于某种原因,它无法正常工作。图像会稍微放大,然后反弹。谢谢。

这是变焦功能

func zoom(sender:UIPinchGestureRecognizer) {


    if sender.state == .Ended || sender.state == .Changed {

        let currentScale = self.view.frame.size.width / self.view.bounds.size.width
        var newScale = currentScale*sender.scale

        if newScale < 1 {
            newScale = 1
        }
        if newScale > 9 {
            newScale = 9
        }

        let transform = CGAffineTransformMakeScale(newScale, newScale)

        self.imageView?.transform = transform
        sender.scale = 1

    }

}

11
您可以使用ImageScrollView开放源代码,可缩放和可滚动的图像视图。github.com/huynguyencong/ImageScrollView
huync

4
^^^对我来说效果很好,大约花了30秒。谢谢
36 By Design

Answers:


132

UIImageView用UIScrollView捏缩放 Swift 3和Xcode 8字母 Youtube视频URL中的图像缩放ios

在情节提要中设置uiscrollview委托 在此处输入图片说明

 class PhotoDetailViewController: UIViewController, UIScrollViewDelegate {

    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var imgPhoto: UIImageView!
      
    override func viewDidLoad() {
        
        super.viewDidLoad()
    
        scrollView.minimumZoomScale = 1.0
        scrollView.maximumZoomScale = 6.0        
        // scrollView.delegate = self - it is set on the storyboard.
    }  
        
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
       
        return imgPhoto
    }

4
卓越!确实如这篇文章所说的那样简单!
instanceof

1
这应该是Swift 3的公认答案。我没有尝试过其他任何方法,包括上面的公认答案。
hawmack13

1
不需要在代码中设置滚动视图委托,因为它已通过情节提要板设置,如上图所示。
C6Silver '17

我是swift和xcode的新手,我试图在包含图像的表视图中执行相同的操作,每个表单元格都有自己的后端。所以我试图把委托作为每个表单元的后端,但它不起作用。完成上述步骤后,我还有什么想念的吗?
Joel Wahlund

好答案!我喜欢简单性(没有不必要的子类等),并且它在没有情节
提要的情况下

53

我决定将imageView添加到UIScrollView中。它允许用户缩放和平移。这是我使用的代码。

为了设置最大/最小缩放,我使用了:

    scrollImg.minimumZoomScale = 1.0
    scrollImg.maximumZoomScale = 10.0

这是其余的代码。

    var vWidth = self.view.frame.width
    var vHeight = self.view.frame.height

    var scrollImg: UIScrollView = UIScrollView()
    scrollImg.delegate = self
    scrollImg.frame = CGRectMake(0, 0, vWidth!, vHeight!)
    scrollImg.backgroundColor = UIColor(red: 90, green: 90, blue: 90, alpha: 0.90)
    scrollImg.alwaysBounceVertical = false
    scrollImg.alwaysBounceHorizontal = false
    scrollImg.showsVerticalScrollIndicator = true
    scrollImg.flashScrollIndicators()

    scrollImg.minimumZoomScale = 1.0
    scrollImg.maximumZoomScale = 10.0

    defaultView!.addSubview(scrollImg)

    imageView!.layer.cornerRadius = 11.0
    imageView!.clipsToBounds = false
    scrollImg.addSubview(imageView!)

我也必须添加它

func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
    return self.imageView
}

Swift 3及以上功能原型

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return self.mainImage
}

下去,检查“ akhilendra-singh”的答案。这个答案并不完美。
Irshad Mohamed

22

支持Swift 5.1,您可以创建的扩展UIImageView,如下所示:

extension UIImageView {
  func enableZoom() {
    let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(startZooming(_:)))
    isUserInteractionEnabled = true
    addGestureRecognizer(pinchGesture)
  }

  @objc
  private func startZooming(_ sender: UIPinchGestureRecognizer) {
    let scaleResult = sender.view?.transform.scaledBy(x: sender.scale, y: sender.scale)
    guard let scale = scaleResult, scale.a > 1, scale.d > 1 else { return }
    sender.view?.transform = scale
    sender.scale = 1
  }
}

8
喜欢这个解决方案。可以向左滚动吗?@John Lima
Naveed Ahmad

16

快速选项4

class ViewController: UIViewController, UIScrollViewDelegate {

@IBOutlet weak var scrolView: UIScrollView!
@IBOutlet weak var imgPhoto: UIImageView!

  override func viewDidLoad() {
    super.viewDidLoad()
    scrolView.delegate = self
    scrolView.minimumZoomScale = 1.0
    scrolView.maximumZoomScale = 10.0
  }

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

2
捏完后,致电scrollView.zoomScale = 1.0
Marco Leong

工作解决方案,谢谢
Naveed Ahmad

12

您可以使用ImageScrollView开源,可缩放和可滚动的图像视图。http://github.com/huynguyencong/ImageScrollView

像这个开源程序一样,将ImageView添加到ScrollView

open class ImageScrollView: UIScrollView {
   var zoomView: UIImageView? = nil
}

extension ImageScrollView: UIScrollViewDelegate{

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

    public func scrollViewDidZoom(_ scrollView: UIScrollView) {
        adjustFrameToCenter()
    }
}

我认为这是最好的答案。它是可缩放的,也可滚动的。此外,它还支持双击选项卡。
mazend

1
我想再说一件事。真的很容易使用。
mazend

6

我认为问题在于您对currentScale的确定。它始终等于1,因为您更改了imageView的比例。您应按以下方式分配currentScale:

let currentScale = self.imageView?.frame.size.width / self.imageView?.bounds.size.width  

6

Swift 3解决方案

默认情况下UIImageView's userInteration处于禁用状态。在中添加任何手势之前将其启用UIImageView

imgView.isUserInteractionEnabled = true

相对于屏幕坐标中两次触摸的点的比例因子

var lastScale:CGFloat!
func zoom(gesture:UIPinchGestureRecognizer) {
    if(gesture.state == .began) {
        // Reset the last scale, necessary if there are multiple objects with different scales
        lastScale = gesture.scale
    }
    if (gesture.state == .began || gesture.state == .changed) {
    let currentScale = gesture.view!.layer.value(forKeyPath:"transform.scale")! as! CGFloat
    // Constants to adjust the max/min values of zoom
    let kMaxScale:CGFloat = 2.0
    let kMinScale:CGFloat = 1.0
    var newScale = 1 -  (lastScale - gesture.scale)
    newScale = min(newScale, kMaxScale / currentScale)
    newScale = max(newScale, kMinScale / currentScale)
    let transform = (gesture.view?.transform)!.scaledBy(x: newScale, y: newScale);
    gesture.view?.transform = transform
    lastScale = gesture.scale  // Store the previous scale factor for the next pinch gesture call
  }
}

2
尝试清楚地说明... lastScale是什么,这里的新缩放是什么,您在哪里声明了它们,它们的子类是什么
srivas

能否请您在此处添加更多详细信息。代码不完整。最新的磅秤是多少?
aBilal17

结束捏捏@ rajeshkumar-r时如何恢复原始大小
reza_khalafi

6

使用Swift 5.0,这对我来说是这样的:

let myImageView = UIImageView(image: myImage)
myImageView.isUserInteractionEnabled = true
let pinchMethod = UIPinchGestureRecognizer(target: self, action: #selector(pinchImage(sender:)))
myImageView.addGestureRecognizer(pinchMethod)

@objc func pinchImage(sender: UIPinchGestureRecognizer) {
  guard let sender.view != nil else { return }

if let scale = (sender.view?.transform.scaledBy(x: sender.scale, y: sender.scale)) {
  guard scale.a > 1.0 else { return }
  guard scale.d > 1.0 else { return }
  sender.view?.transform = scale
  sender.scale = 1.0
 }
}

您可以使用scale.a,scale.b,scale.c,scale.d,scale.tx和scale.ty来设置规模限制。


5

Swift 3解决方案

这是我使用的代码。我添加了imageView到scrollView作为子视图。

class ZoomViewController: UIViewController,UIScrollViewDelegate {

@IBOutlet weak var scrollView:UIScrollView!
@IBOutlet weak var imageView:UIImageView!

override func viewDidLoad() {

        super.viewDidLoad()
        scrollView.delegate = self

        scrollView.minimumZoomScale = 1.0
        scrollView.maximumZoomScale = 10.0//maximum zoom scale you want
        scrollView.zoomScale = 1.0

}

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

1

我认为最大的问题是你的最后func,你有sender.scale = 1。如果您删除该行代码,则图像不应每次都反弹。



1

这是一个古老的问题,但是我看不到任何答案来解释原始代码有什么问题。

这行:

let currentScale = self.view.frame.size.width / self.view.bounds.size.width

正在主视图而不是imageView上工作,因此比例计算始终为〜1

这个简单的更改使其表现出预期

let currentScale = sender.view!.frame.size.width / sender.view!.bounds.size.width

通过将自身更改为发件人(并强制视图展开),比例计算将按预期进行。


0

我到这里结束,可能是搜索错误的方式。

我将imageView设置为contentMode = .centre之后。但是我判断它也放大了,我正在寻找一种缩小它的方法。这是如何做:

    self.imageView.contentScaleFactor = 3

1就像您在做什么一样。1缩小更多... 3适用于我,但您需要对其进行测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.