web-dev-qa-db-fra.com

Zoom pincement UIImageView swift

J'espérais que quelqu'un pourrait m'aider. J'essaie de permettre à un utilisateur de pincer le zoom sur un UIImageView (avec un niveau maximum et minimum autorisés). Mais pour une raison quelconque, cela ne fonctionne pas correctement. L'image s'agrandit un peu puis rebondit. Je vous remercie.

voici le zoom func

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

J'ai décidé d'ajouter l'imageView à un UIScrollView. Il permet à l'utilisateur de zoomer et de faire un panoramique. Voici le code que j'ai utilisé.

pour régler le zoom max/min, j'ai utilisé:

    scrollImg.minimumZoomScale = 1.0
    scrollImg.maximumZoomScale = 10.0

voici le reste du code.

    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!)

Je devais aussi ajouter ceci aussi

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

prototype de fonction Swift 3 et supérieur

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

Zoom à pincement UIImageView avec UIScrollView || zoom de l'image ios en Swift 3 et Xcode 8 lettre RL de la vidéo Youtube

définir uiscrollview Delegate dans le storyboard 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

L’option pour 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

Vous pouvez utiliser ImageScrollView Open Source, une vue zoomable et défilable. http://github.com/huynguyencong/ImageScrollView

Comme cette source ouverte, ajoutez 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

À mon avis, le problème est votre détermination de currentScale. Il est toujours égal à 1, car vous modifiez l'échelle de votre imageView. Vous devez affecter votre currentScale comme suit:

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

Swift 3 solution

Par défaut UIImageView'suserInteration est désactivé. Activez-le avant d'ajouter des gestes dans UIImageView.

imgView.isUserInteractionEnabled = true

Le facteur d'échelle relatif aux points des deux touches en coordonnées d'écran

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 solution

C'est le code que j'ai utilisé. J'ai ajouté imageView à scrollView en tant que sous-vue.

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

Je me suis retrouvé ici, cherchant probablement le mauvais chemin.

J'étais après avoir mon imageView dans contentMode = .centre. Mais je jugeais que le zoom était trop important et que je cherchais un moyen de faire un zoom arrière. Voici comment:

    self.imageView.contentScaleFactor = 3

1 est comme si vous faisiez quelque chose. Plus que 1 effectue un zoom arrière ... 3 fonctionne pour moi, mais vous devez le tester.

0
iOS Flow

J'ai posté une réponse ici pour la fonctionnalité de zoom avec à la fois pincer et taper deux fois Swift 3. Fonctionne parfaitement.

0
Akhilendra Singh

Je pense que le plus gros problème est à la fin de votre func, vous avez sender.scale = 1. Si vous supprimez cette ligne de code, votre image ne doit pas simplement rebondir à chaque fois.

0
Logan

En utilisant Swift 5.0, voici comment cela fonctionne pour moi:

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

Vous pouvez utiliser scale.a, scale.b, scale.c, scale.d, scale.tx et scale.ty pour définir vos limites d’échelle.

0
Gabriel Sória

C'est une vieille question, mais je ne vois aucune réponse qui explique ce qui ne va pas avec le code original.

Cette ligne:

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

Travaille sur la vue principale plutôt que sur l'imageView afin que le calcul de l'échelle soit toujours ~ 1

Ce simple changement le fait se comporter comme prévu

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

en se changeant en expéditeur (et en obligeant la vue à se défaire), le calcul de la balance fonctionne comme prévu.

0
Dean Ward