如何在UIScrollView中旋转imageView并重新计算contentSize,bounds和frame

时间:2016-07-06 22:11:59

标签: swift uiscrollview uiimageview uigesturerecognizer image-rotation

我在UIScrollView中旋转图像时遇到问题,我的视图层次结构描述如下:
我有一个UIVcrollView,UIView作为子视图。 UIView有一个UIImageView作为子视图。

我可以在其中旋转imageView,然后重新计算scrollView的contentSize,以便能够平移所有内容。

我正在使用此代码:

//
//  TestView.swift
//

import UIKit

class TestView: UIView {

    // MARK: - properties
    private var imageView: UIImageView?
    private var zoomingView: UIView?
    private var scrollView: UIScrollView?
    private let kDecayRotation = "kDecayRotation"
    var image: UIImage? {
        didSet {
            setupImageView(image)
        }
    }


    // MARK: - init
    convenience init(frame: CGRect, image: UIImage) {
        self.init(frame: frame)
        setupImageView(image)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.blueColor()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    // MARK: - methods
    private func setupImageView(image: UIImage?) {
        guard let image = image else { return }

        imageView = UIImageView(image: image)

        zoomingView = UIView(frame: imageView!.frame)
        zoomingView?.addSubview(imageView!)

        scrollView = UIScrollView(frame: frame)
        scrollView?.backgroundColor = UIColor.redColor()
        scrollView?.contentSize = zoomingView!.frame.size
        scrollView?.addSubview(zoomingView!)
        addSubview(scrollView!)

        let rotationGesture = UIRotationGestureRecognizer(target: self, action: #selector(handleRotation(_:)))
        rotationGesture.delegate = self
        scrollView?.addGestureRecognizer(rotationGesture)
    }

    @objc private func handleRotation(gestureRecognizer: UIRotationGestureRecognizer) {
        adjustAnchorPointForGestureRecognizer(gestureRecognizer)

        guard let targetView = zoomingView else { return }

        if gestureRecognizer.state == .Began {  }
        else if gestureRecognizer.state == .Changed {

            targetView.transform = CGAffineTransformRotate(targetView.transform, gestureRecognizer.rotation)
            gestureRecognizer.rotation = 0

            scrollView?.contentSize = targetView.frame.size
            var targetFrame = targetView.frame
            let targetBounds = targetView.bounds
            targetFrame.origin.x = 0
            targetFrame.origin.y = 0
            targetView.frame = targetFrame
            targetView.bounds = targetBounds

            scrollView?.setNeedsDisplay()

        } else if gestureRecognizer.state == .Cancelled || gestureRecognizer.state == .Ended {  }
    }

    // MARK: - gesture helper
    private func adjustAnchorPointForGestureRecognizer(gestureRecognizer: UIGestureRecognizer) {
        guard let zoomingView = zoomingView else { return }
        if gestureRecognizer.state == .Began {
            let locationInView = gestureRecognizer.locationInView(zoomingView)
            let locationInSuperview = gestureRecognizer.locationInView(zoomingView.superview)

            zoomingView.layer.anchorPoint = CGPointMake(locationInView.x / zoomingView.bounds.size.width, locationInView.y / zoomingView.bounds.size.height)
            zoomingView.center = locationInSuperview
        }
    }
}

extension TestView: UIGestureRecognizerDelegate {
    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

问题是:

  • 视图不会围绕手指的位置旋转(虽然我实现了计算新锚点的方法)
  • 如果正确重新计算了contentSize(我在 handleRotation(_:)中评论 adjustAnchorPointForGestureRecognizer(gestureRecognizer)),但图片移动以可怕的方式穿过滚动视图。如何使图像的效果保持固定(和旋转),并在“沉默”中重新计算内容大小。方式?

修改1

这是测试图像: test image

使用TestView的代码是:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()
    }

    private func setupView() {
        let sampleImage = UIImage(named: "testImage")
        let testView = TestView(frame: view.frame, image: sampleImage!)
        view.addSubview(testView)
    }
}

0 个答案:

没有答案