Swift:无法将ImageView放在ScrollView的中心

时间:2019-03-16 10:17:37

标签: swift uiscrollview uiimageview

我正在尝试在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

有人会建议我想念什么吗?

2 个答案:

答案 0 :(得分:0)

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

viewWillLayoutSubviews

似乎可以正常工作。

答案 1 :(得分: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
}