web-dev-qa-db-ja.com

UIImageViewピンチズームswift

誰かが私を助けてくれることを望んでいた。ユーザーが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

    }

}
47
RandomBytes

ImageScrollを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
}
44
RandomBytes

UIScrollViewによるUIImageViewピンチズーム|| Swift 3およびXcode 8レターの画像ズームiOSYoutube video URL

ストーリーボードにuiscrollviewデリゲートを設定 enter image description here

 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
    }
107
Parth Changela

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
  }
}
12
Heretic Sic

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
huync

私の見解では、問題はcurrentScaleの決定です。 imageViewのスケールを変更するため、常に1になります。次のようにcurrentScaleを割り当てる必要があります。

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

Swift 3ソリューション

デフォルトでは、UIImageView'suserInterationは無効になっています。 UIImageViewにジェスチャーを追加する前に有効にします。

imgView.isUserInteractionEnabled = true

画面座標の2つのタッチのポイントに相対的なスケール係数

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
  }
}
5
RajeshKumar R

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

おそらく間違った方法で検索してしまいました。

ContentMode = .centreでimageViewを取得した後です。しかし、私はそれがズームインしすぎていると判断し、ズームアウトする方法を探していました。方法は次のとおりです。

    self.imageView.contentScaleFactor = 3

1は、何かをしているようです。 1つ以上がズームアウトします... 3つは私には有効ですが、テストする必要があります。

0
iOS Flow

Swift 3.のピンチとダブルタップの両方を使用したズーム機能について、回答を投稿しました こちら

0

最大の問題は、funcの最後にあると思います。sender.scale = 1があります。そのコード行を削除すると、毎回画像が跳ね返るだけではなりません。

0
Logan

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: UIPinchMethodRecognizer) {
  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を使用して、スケール制限を設定できます。

0
Gabriel Sória

これは古い質問ですが、元のコードの何が問題なのかを説明する答えは見当たりません。

この行:

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
Dean Ward