Swift:无法在ScrollView上居中ImageView

问题描述 投票:0回答:2

我试图在X和Y轴的中心显示一个imageViewscrollView,当我运行应用程序时,它恰好适合设备的宽度。我也想要平移和缩放imageView。我已经尝试了几乎所有已经发布在SO上的解决方案,并且也遵循了这个tutorial但不知何故它只是没有解决我的问题。图像是从PDF生成的。

我以编程方式进行布局。到目前为止我的实施:

let scrollView: UIScrollView = {
    let sv = UIScrollView()
    sv.translatesAutoresizingMaskIntoConstraints = false
    sv.backgroundColor = .lightGray
    return sv
}()

let imageView: UIImageView = {
    let iv = UIImageView()
    iv.translatesAutoresizingMaskIntoConstraints = false
    iv.contentMode = .scaleAspectFill
    return iv
}()

override func viewDidLoad() {
    super.viewDidLoad()
    scrollView.delegate = self

    view.addSubview(scrollView)
    scrollView.addSubview(imageView)

    NSLayoutConstraint.activate([
        scrollView.topAnchor.constraint(equalTo: view.topAnchor),
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),

        imageView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 10),
        imageView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 10),
        imageView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -10),
        imageView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -10),

        ])

    imageView.image = obtainThumbnail()
}

fileprivate func updateMinZoomScaleForSize(_ size: CGSize) {
    let widthScale = size.width / imageView.bounds.width
    let heightScale = size.height / imageView.bounds.height
    let minScale = min(widthScale, heightScale)

    scrollView.minimumZoomScale = minScale
    scrollView.zoomScale = minScale
}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    updateMinZoomScaleForSize(view.bounds.size)
}

func obtainThumbnail() -> UIImage? {
    guard let url = Bundle.main.url(forResource: "drawings", withExtension: "pdf") else {return nil}

    guard
        let data = try? Data(contentsOf: url),
        let page = PDFDocument(data: data)?.page(at: 0) else {
            return nil
    }

    let pageSize = page.bounds(for: .mediaBox)
    return page.thumbnail(of: CGSize(width: pageSize.width, height: pageSize.height), for: .mediaBox)
}

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

当我运行应用程序时,这是我想要的结果。 enter image description here

这是我现在运行应用程序时的结果,过度拉伸。 enter image description here

有人会建议我缺少什么吗?

swift uiscrollview uiimageview
2个回答
0
投票

我认为视图在UIViewControllers中延迟加载,因此稍后在UI生命周期中进行计算应该可以解决问题。删除viewWillLayoutSubviews中的调用,而不是使用:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    updateMinZoomScaleForSize(view.bounds.size)
}

似乎工作。


0
投票

为了使其运行良好,有两个地方需要解决:

  override func viewDidLoad() {
    super.viewDidLoad()
    scrollView.delegate = self

    view.addSubview(scrollView)
    scrollView.addSubview(imageView)

    NSLayoutConstraint.activate([

        scrollView.topAnchor.constraint(equalTo: view.topAnchor),
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),

       //First place.
       // scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
       // scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),
        scrollView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0.0),



        imageView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 10),
        imageView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 10),
        imageView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -10),
        imageView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -10),


        ])

    imageView.backgroundColor = UIColor.red
    imageView.image = UIImage.init(named: "temp2.png")
     //second place.
    imageView.sizeToFit()

希望它能很好地解决你的问题。

如果您需要中间的视图,可以尝试以下方法:

let scrollView: UIScrollView = {
    let sv = UIScrollView()
    sv.translatesAutoresizingMaskIntoConstraints = false
    sv.backgroundColor = .lightGray
  sv.contentMode = .center

 return sv
}()

 let imageView: UIImageView = {
    let iv = UIImageView()
    iv.translatesAutoresizingMaskIntoConstraints = true
    iv.contentMode = .scaleAspectFill
    return iv
}()

override func viewDidLoad() {
    super.viewDidLoad()
    scrollView.delegate = self

    view.addSubview(scrollView)
    scrollView.addSubview(imageView)



    NSLayoutConstraint.activate([


     scrollView.centerYAnchor.constraint(equalTo: view.centerYAnchor ),

    scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor ),


        scrollView.contentLayoutGuide.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
   scrollView.contentLayoutGuide.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor),


        ])

    imageView.backgroundColor = UIColor.red
    imageView.image = UIImage.init(named: "temp2.png")
    imageView.sizeToFit()
    updateMinZoomScaleForSize(view.bounds.size)


}


var constantHeight : CGFloat{

    return  min(view.bounds.height, imageView.bounds.height *  scrollView.zoomScale)
}
var constantWidth : CGFloat{
    return min( view.bounds.width, imageView.bounds.width *  scrollView.zoomScale)
}

    lazy var constraintHeight: NSLayoutConstraint = {

     return      scrollView.contentLayoutGuide.heightAnchor.constraint(equalToConstant: constantHeight)

}()

    lazy  var constraintWeight: NSLayoutConstraint = {
    return
        scrollView.contentLayoutGuide.widthAnchor.constraint(equalToConstant: constantWidth)

}()



fileprivate func updateMinZoomScaleForSize(_ size: CGSize) {

    let widthScale = size.width / imageView.bounds.width
    let heightScale = size.height / imageView.bounds.height
    let minScale = min(widthScale, heightScale)

    imageView.frame = CGRect.init(x: 0, y: 0, width: minScale * imageView.bounds.width, height: minScale*imageView.bounds.height)


    scrollView.maximumZoomScale = 10.0
    scrollView.zoomScale = 1.0



    constraintHeight.isActive = true
  constraintWeight.isActive = true


}




func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat){

    constraintHeight.constant = constantHeight
    constraintWeight.constant  = constantWidth
    scrollView.clipsToBounds = true

}


func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
   scrollView.clipsToBounds = false
}


func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return imageView
}
© www.soinside.com 2019 - 2024. All rights reserved.