UIImageView 上的捏合、平移和双击手势

Posted

技术标签:

【中文标题】UIImageView 上的捏合、平移和双击手势【英文标题】:Pinch, Pan and Double tap gesture on UIImageView 【发布时间】:2021-11-30 18:47:44 【问题描述】:

我想在具有以下限制的图像视图上应用这些手势:

1)双击:缩放图像两次,然后返回原始大小

2)Pinch:缩放图像,最大限制和最小限制为原始大小

3)平移:缩放图像时,移动图像和图像视图不应平移超过边界之一

我使用教程尝试了以下代码,但平移无法正常工作,我认为有时也会影响其他手势:

请让我知道我做错了什么。

属性:

var originalFrame = CGRect()
var initialCenter = CGPoint()  // The initial center point of the view.
var imgTapCount = 0
var lastScale: CGFloat = 1.0
var minScale = 1.0
var maxScale = 4.0
var imageCurrentScale = 1.0

viewDidLoad()我调用以下函数

func displayImage() 
   //imgView gets image assigned here from Url
    originalFrame = imgView.frame

点击手势:

@IBAction func imgTapGesture(_ sender: UITapGestureRecognizer) 
        guard sender.view != nil else return
        if imgTapCount < 2 
            let pinchCenter = CGPoint(x: sender.location(in: view).x - view.bounds.midX,
                                      y: sender.location(in: view).y - view.bounds.midY)
            let transform = sender.view?.transform.translatedBy(x: pinchCenter.x, y: pinchCenter.y)
                .scaledBy(x: 2, y: 2)
                .translatedBy(x: -pinchCenter.x, y: -pinchCenter.y)
            sender.view?.transform = transform!
         else 
            UIView.animate(withDuration: 0.2, animations: 
                sender.view?.transform = CGAffineTransform.identity
            )
        
        if imgTapCount < 2 
            imgTapCount += 1
         else 
            imgTapCount = 0
        
    

平移手势

@IBAction func imgPanGesture(_ sender: UIPanGestureRecognizer) 
    guard sender.view != nil else return
    let piece = sender.view!
    // Get the changes in the X and Y directions relative to
    // the superview's coordinate space.
    let translation = sender.translation(in: piece.superview)
    if sender.state == .began 
        // Save the view's original position.
        self.initialCenter = piece.center
    
    // Update the position for the .began, .changed, and .ended states
    if sender.state != .cancelled 
        // Add the X and Y translation to the view's original position.
       
        if (imgView.frame.width > piece.superview!.frame.width || imgView.frame.height > piece.superview!.frame.height) && (((imgView.frame.minX <= originalFrame.minX) || (imgView.frame.maxX >= originalFrame.maxX)) || (imgView.frame.minY <= originalFrame.minY) || (imgView.frame.maxY >= originalFrame.maxY)) 
            let newCenter = CGPoint(x: initialCenter.x + translation.x, y: initialCenter.y + translation.y)
            print(newCenter)
            piece.center = newCenter
        
     else 
        // On cancellation, return the piece to its original location.
        piece.center = initialCenter
    

捏合手势

@IBAction func imgPinchGesture(_ sender: UIPinchGestureRecognizer) 
    var newScale = sender.scale
    if sender.state == .began 
        lastScale = self.imgView.frame.width/self.imgView.bounds.size.width
    
    newScale = newScale * lastScale
    
    if newScale < minScale 
        newScale = minScale
     else if newScale > maxScale 
        newScale = maxScale
    
    
    let currentScale = self.imgView.frame.width/self.imgView.bounds.size.width
    self.imgView.transform = CGAffineTransform(scaleX: newScale, y: newScale)
        print("last Scale: \(lastScale), current scale: \(currentScale), new scale: \(newScale), gestureRecognizer.scale: \(sender.scale)")

【问题讨论】:

@Vollan 我必须将图像缩放两次,然后返回原始大小。所以我为此使用了 imgTapCount 变量。我已经在情节提要上将手势点击次数设置为 2 如果你只想捏平和双击,你应该使用 pdf 视图 我有两个选择给你 1 使用 PDFView 显示图像。 (简单高效) 2 使用带有图像的可缩放滚动视图。 (冗长而凌乱) @ZeeshanAhmed 如何实现 PDFView? 【参考方案1】:
 lazy var pdfView: PDFView = 
    let pdfView = PDFView()
    pdfView.displaysPageBreaks = true
    pdfView.enableDataDetectors = true
    pdfView.subviews[0].backgroundColor = .clear
    pdfView.maxScaleFactor = 4
    return pdfView
()

然后在声明 pdf 视图后,您应该添加一个将图像转换为 pdfdocument 的函数

func createPDF(image: UIImage) -> PDFDocument 
 let document = PDFDocument()

 guard let cgImage = image.cgImage else  return document 

 let image = UIImage(cgImage: cgImage, scale: image.scale, orientation: .downMirrored)

 guard let imagePDF = PDFPage(image: image) else  return document 

 document.insert(imagePDF, at: document.pageCount)

 return document

在 viewDidAppear 之后在 viewDidAppear 中查看您的 pdf ...您可以将此 pdfDocument 分配给您的 pdf

pdfView.document = createPDF(image: "yourImage")
pdfView.autoScale = true

【讨论】:

以上是关于UIImageView 上的捏合、平移和双击手势的主要内容,如果未能解决你的问题,请参考以下文章

如果视图注册平移手势,则捏合手势不起作用

UIScrollView 并取消缩放捏合手势

在 UITableViewCell 的子视图上添加单击和双击手势

带有平移、旋转和捏合手势的 UIKit Dynamics

通过手势识别器操作后裁剪 UIImageView

使用平移、旋转和捏合手势编辑后如何保存 UIImage