UIScrollView中的UIImageView无法正确缩放

时间:2018-08-03 09:02:33

标签: ios swift uiscrollview uiimageview

我想允许用户侧移图像。图像应缩放到设备的高度,并且用户只能左右滚动。用户不应该能够缩放。 我有一个UIViewController,向其中添加了一个自定义子类ImageScrollView。 应该以全高度显示图像,但是图像基本上是不缩放显示的。即使正确缩放了zoomScale,也没有效果。

我在做什么错了?

谢谢

override func viewDidLoad() {
        super.viewDidLoad()

        let i = UIImage(named: "test.jpg")

        let iSV = ImageScrollView(image: i)
        self.view.addSubview(iSV)
        iSV.fillSuperview()
}

class ImageScrollView: UIScrollView {

    let image: UIImage
    let imageView = UIImageView()

    init(image img: UIImage) {    
        image = img
        imageView.image = image

        super.init(frame: .zero)

        self.addSubview(imageView)
        imageView.fillSuperview()

        self.contentSize = image.size

        self.showsHorizontalScrollIndicator = false
        self.showsVerticalScrollIndicator = false
    }

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

    override func layoutSubviews() {
        super.layoutSubviews()
        self.zoomScale = getZoomScale()    
    }

    func getZoomScale() -> CGFloat{
        let boundSize = self.frame.size
        let yScale = boundSize.height / image.size.height
        return yScale   
    }    
}

就与自动布局有关的情况而言,我加入了fillSuperview扩展名。

extension UIView {    
    public func fillSuperview() {
        translatesAutoresizingMaskIntoConstraints = false
        if let superview = superview {
            topAnchor.constraint(equalTo: superview.topAnchor, constant: 0).isActive = true
            leftAnchor.constraint(equalTo: superview.leftAnchor, constant: 0).isActive = true
            bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: 0).isActive = true
            rightAnchor.constraint(equalTo: superview.rightAnchor, constant: 0).isActive = true
        }
    }
}

2 个答案:

答案 0 :(得分:1)

由于您不希望图像缩放,因此我建议您不要理会缩放控件。 UIImageView知道如何缩放其内容。

我建议您这样做:

  1. 添加一个约束,将imageView的高度设置为与scrollView的高度相等。这样可以防止垂直滚动。
  2. 添加一个约束,该约束使用乘数image.size.width / image.size.height将imageView宽度设置为等于imageView高度。
  3. 将imageView内容模式设置为.scaleToFill

要允许您更改图像,请保留一个aspectRatio属性,该属性保留在步骤2中设置的宽高比约束。设置aspectRatio.isActive = false,然后为新图像创建并激活新的约束。

此外,如果您缩放后的图像可能不够宽,无法在水平方向上水平填充scrollView,请考虑以下更改:

  1. 将设置imageView宽度的约束替换为使用乘数max(image.size.width / image.size.height, scrollView.bounds.width / scrollView.bounds.height)将约束设置为等于imageView高度的约束。
  2. 将imageView内容模式设置为.scaleAspectFit

然后,当您的图像狭窄时,imageView将填充scrollView,但是.scaleAspectFit将显示整个图像,并以scrollView为中心。这对于宽图像仍然可以正常使用,因为乘数将与图像的长宽比匹配,并且.scaleAspectFit将填充整个imageView。

答案 1 :(得分:0)

您忘记实现滚动视图委托。并设置滚动视图的最小和最大缩放级别。

var iSV: ImageScrollView?

let i = UIImage(named: "noWiFi")!
iSV = ImageScrollView(image: i)
if let iSV = iSV {
    self.view.addSubview(iSV)
    iSV.fillSuperview()
    iSV.delegate = self
}

override func viewDidLayoutSubviews() {
        if let iSV = iSV {
            let scale = iSV.getZoomScale()
            iSV.minimumZoomScale = scale
            iSV.maximumZoomScale = scale
        }
}

extension ViewController: UIScrollViewDelegate {
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return iSV?.imageView
    }
}

注意:我只是做得粗糙。它可能无法满足您的完整要求