【问题标题】:UIImageView in UIScrollView does not zoom correctlyUIScrollView 中的 UIImageView 不能正确缩放
【发布时间】:2019-01-11 03:11:12
【问题描述】:

我想允许用户侧平移图像。图像应该缩放到设备的高度,并且用户应该只能左右滚动。用户不应该能够缩放。 我有一个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
        }
    }
}

【问题讨论】:

    标签: ios swift uiscrollview uiimageview


    【解决方案1】:

    由于您不希望图像缩放,我建议您甚至不要使用缩放控件。 UIImageView 知道如何缩放其内容。

    我建议你这样做:

    1. 添加一个将 imageView 高度设置为等于 scrollView 高度的约束。这将防止垂直滚动。
    2. 添加一个约束,将 imageView 的宽度设置为等于 imageView 的高度,乘数为image.size.width / image.size.height
    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。

    【讨论】:

    • 谢谢 - 这解决了我的问题。我开始与您聊天以解决后续问题,以免评论部分溢出。
    【解决方案2】:

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

    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
        }
    }
    

    注意:我只是粗暴了。它可能无法满足您的全部要求

    【讨论】:

    • 您好,感谢您的回复。我没有意识到我必须实现委托方法,因为我不希望用户能够缩放。我试过了,结果还是一样。即使.getZoomScale() 返回 0.1929,图像 (5184x3456) 仍显示为未缩放
    • 您使用哪种设备进行测试?由于我们将minimumZoomScalemaximumZoomScale 设置为相同的值,因此用户无法放大/缩小。
    猜你喜欢
    • 2012-11-24
    • 2012-02-12
    • 2017-01-06
    • 2019-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    相关资源
    最近更新 更多