【问题标题】:Zooming an UIImageView that contains subviews缩放包含子视图的 UIImageView
【发布时间】:2019-09-08 16:56:47
【问题描述】:

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

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

它对UIImageView 非常有效。

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

【问题讨论】:

  • 你为什么不把它们放在滚动视图之外呢?或者在第一个透明背景上方的另一个滚动视图中?
  • @MaticOblak 我需要子视图在图像视图中的位置。
  • 那我不明白你的问题是什么。就像图像缩放时子视图应该改变位置但它们不应该改变它们的大小一样?有点像地图上的注释;当您放大它们时,它们仍然指向同一个位置图,但它们的大小没有增加?您可以使用 UIView 中的“转换”方法。将原始坐标从图像视图转换为滚动视图的超级视图,并将注释移到那里。只需更新 scrollViewDidScroll 上的位置
  • 是的,就像地图上的注释一样。我会试试的,谢谢。

标签: ios swift uiscrollview uiimageview zooming


【解决方案1】:

有很多方法可以实现这一点。我想说最简单的方法是简单地缩小您的视图。这是我用作演示的:

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) 即可完成所有工作。即使使用约束也应该没问题。

【讨论】:

    【解决方案2】:

    位于 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-13
      • 1970-01-01
      相关资源
      最近更新 更多