【问题标题】:UIImageView pinch zoom swiftUIImageView 捏缩放 swift
【发布时间】:2015-07-12 21:37:17
【问题描述】:

我希望有人可以帮助我。我试图允许用户在 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

    }

}

【问题讨论】:

标签: swift uiimageview uipinchgesturerecognizer


【解决方案1】:

UIImageView 用 UIScrollView 捏缩放 || swift 3 和 Xcode 8 字母中的图像缩放 ios Youtube video URL

在情节提要中设置 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
    }

【讨论】:

  • 了不起!真的就像这篇文章说的那么简单!
  • 这应该是 Swift 3 的公认答案。我尝试过的其他方法都没有,包括上面接受的答案。
  • 不需要在代码中设置滚动视图委托,因为它已经通过情节提要设置,如上图所示。
  • 我对 swift 和 xcode 非常陌生,我试图在包含图像的 tableview 中做同样的事情,每个 tablecell 都有自己的后端。所以我试图将委托作为每个表格单元的后端,但它不起作用。做了上面的步骤,有什么我遗漏的吗?
  • 很好的答案!我喜欢简单(没有不必要的子类等)并且它在没有情节提要的情况下也能很好地工作(只需要设置委托并使用添加 UIImageView 作为 UIScrollView 的子视图。
【解决方案2】:

我决定将 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" 的答案。这个答案并不完美。
【解决方案3】:

支持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
  }
}

【讨论】:

  • 喜欢这个解决方案。可以左右滚动吗? @约翰利马
  • 我发现这总是在同一个区域放大,无论你在哪里捏放大。有没有办法在你捏缩放的地方进行这种缩放?
  • 使用滚动视图滚动效果更好
【解决方案4】:

swift 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
  }
}

【讨论】:

  • 捏合结束,拨打scrollView.zoomScale = 1.0
  • 工作解决方案,谢谢
【解决方案5】:

您可以使用 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()
    }
}

【讨论】:

  • 我认为这是最好的答案。它是可缩放的,也可滚动的。此外,它还支持双标签操作。
  • 我还想说一件事。它真的很容易使用。
【解决方案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 来设置您的比例限制。

【讨论】:

    【解决方案7】:

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

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

    【讨论】:

      【解决方案8】:

      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
        }
      }
      

      【讨论】:

      • 尽量解释清楚...lastScale是什么这里是新的scale,你在哪里声明它们,它们的子类是什么
      • 您能否在此处添加更多详细信息。代码不完整。 lastScale 是什么?这里有什么新的比例?
      • 结束捏@rajeshkumar-r时如何恢复到原始大小
      【解决方案9】:

      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
      }
      

      【讨论】:

        【解决方案10】:

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

        【讨论】:

          【解决方案11】:

          我发布了一个答案 here,用于在 Swift 3 中使用捏合和双击进行缩放功能。完美运行。

          【讨论】:

          • !!!!开发者注意!!!这是一个完美的答案。这甚至适用于具有非常小的自动校正功能的 Swift 5。
          【解决方案12】:

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

          这一行:

          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
          

          通过将 self 更改为 sender(并强制视图展开)比例计算按预期工作。

          【讨论】:

            【解决方案13】:

            我最终来到了这里,可能是搜索错误的方式。

            我的 imageView 在 contentMode = .centre 之后。 但我判断它太放大了,我正在寻找一种方法来缩小它。 方法如下:

                self.imageView.contentScaleFactor = 3
            

            1 就像你在做任何事情一样。大于 1 缩小... 3 对我有用,但您需要对其进行测试。

            【讨论】:

              猜你喜欢
              • 2019-11-13
              • 2020-10-01
              • 2012-11-24
              • 2017-09-23
              • 1970-01-01
              • 1970-01-01
              • 2011-10-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多