UIImageView щепотка зум быстро

Я надеялся, что кто-нибудь сможет мне помочь. Я пытаюсь позволить пользователю ущипнуть масштабирование 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

    }

}

15 ответов

Решение

Я решил добавить 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
}

UIImageView масштабирование с помощью UIScrollView || Масштабирование изображения ios в Swift 3 и Xcode 8 буквенное видео YouTube 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 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
  }
}

Вариант для 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
  }
}

Вы можете использовать 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()
    }
}

Я использую 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, чтобы установить пределы масштаба.

Swift 3 решение

По умолчанию UIImageView'suserInteration выключен. Включите его, прежде чем добавлять какие-либо жесты в 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
  }
}

На мой взгляд, проблема в вашем определении currentScale. Он всегда равен 1, потому что вы меняете масштаб вашего imageView. Вы должны назначить свою текущую шкалу следующим образом:

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

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
}

[Сентябрь 2022 г., Свифт 5]

Один из способов, которым он, кажется, работает нормально для меня, заключался в том, чтобы встроить представление изображения в представление прокрутки, которое вы можете быстро просмотреть в библиотеке, которой я делюсь, для лучшего понимания, чтобы этот ответ был коротким. Я создал эту небольшую библиотеку и использовал ее в рабочих приложениях. Вы можете установить или просто скопировать и вставить файлы в свой проект. С ним очень легко работать как с UIView и слушать его делегата для получения дополнительных опций, если они вам нужны.

Библиотека называется InteractiveImageView, поддерживает iOS 11.0 и выше, ссылка на GitHub:https://github.com/egzonpllana/InteractiveImageView

Я разместил здесь ответ о функциональности масштабирования с помощью щепотки и двойного нажатия в Swift 3. Работает отлично.

Я думаю, что самая большая проблема в конце вашего func, у тебя есть sender.scale = 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

изменяя себя на отправителя (и заставляя представление развернуть), вычисление масштаба работает как ожидалось.

Подтверждено работа с Xcode 15 | iOS 17 | Свифт 5 | Раскадровка

Я нашел это видео на YouTube ( https://www.youtube.com/watch?v=0Tz0vI721c8) гораздо лучшим примером того, что делать. Это помогает, в частности, с настройкой правильных ограничений.

Я оказался здесь, вероятно, в поисках неправильного пути.

Я был после того, как мой imageView в contentMode = .centre. Но я оценил его слишком увеличенным и искал способ уменьшить его. Вот как:

    self.imageView.contentScaleFactor = 3

1, как будто вы делаете что-нибудь. Больше чем 1 уменьшает... 3 работает для меня, но вы должны проверить это.

Другие вопросы по тегам