缩放包含子视图的 UIImageView

Zooming an UIImageView that contains subviews

我在 UIScrollView(缩放)中有一个 UIImageView 对象。此外,UIImageView 还包含子视图。我正在使用以下函数来放大 UIImageView

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

UIImageView.

效果很好

问题是在缩放这些子视图时,它也会以相同的方式缩放这些子视图。有没有办法禁用这些子视图的缩放?

位于 UIImageView 内部的 UIView 将始终保持相同大小,但将锚定到图像中的特定点(顶部 10%,左侧 10%):

var item: UIView?

override func viewDidLoad() {
    ...
    item = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    setPosition()
    item?.backgroundColor = UIColor.red
    imageView.addSubview(item!)
    ...
}

func setPosition() {
    let x = imageView.frame.size.width/10
    let y = imageView.frame.size.height/10
    item?.frame = CGRect(x: x, y: y, width: 200, height: 200)
}

func scrollViewDidZoom(_ scrollView: UIScrollView) {
    ...
    setPosition()
    ...
}

您可以使用精确数字代替 10%,使用公式:

x = startPosition/startWidthImage*currentWidthImage

有很多方法可以实现这一点。我想说最简单的方法就是简单地倒推您的观点。这是我用作演示的内容:

class ViewController: UIViewController {

    @IBOutlet private var scrollView: UIScrollView?
    private var imageView: UIImageView?
    private var annotations: [UIView] = [UIView]()

    override func viewDidLoad() {
        super.viewDidLoad()

        let imageView = UIImageView(image: UIImage(named: "background"))
        scrollView?.addSubview(imageView)
        scrollView?.contentSize = imageView.bounds.size
        scrollView?.maximumZoomScale = 5.0
        self.imageView = imageView

        scrollView?.delegate = self

        applyAnnotationView({
            let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 10.0, height: 10.0))
            view.backgroundColor = UIColor.red
            view.layer.cornerRadius = view.bounds.width*0.5
            return view
        }(), at: CGPoint(x: 100.0, y: 100.0))

        applyAnnotationView({
            let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 10.0, height: 10.0))
            view.backgroundColor = UIColor.green
            view.layer.cornerRadius = view.bounds.width*0.5
            return view
        }(), at: CGPoint(x: 200.0, y: 200.0))
    }

    func applyAnnotationView(_ view: UIView, at position: CGPoint) {
        view.center = position
        annotations.append(view)
        imageView?.addSubview(view)
    }

}

// MARK: - UIScrollViewDelegate

extension ViewController: UIScrollViewDelegate {

    func scrollViewDidZoom(_ scrollView: UIScrollView) {
        annotations.forEach { item in
            item.transform = CGAffineTransform(scaleX: 1.0/scrollView.zoomScale, y: 1.0/scrollView.zoomScale)
        }
    }

    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return imageView
    }

}

只需应用 CGAffineTransform(scaleX: 1.0/scrollView.zoomScale, y: 1.0/scrollView.zoomScale) 即可完成所有工作。即使使用约束也应该没问题。