设置图像时,UIImageview 未缩放到其帧

UIImageview is not scaling to its frame when image is set

提问人:Arun 提问时间:9/21/2023 最后编辑:HangarRashArun 更新时间:9/22/2023 访问量:32

问:

enter image description here

在这里,我附上了我工作的屏幕截图。我遇到了图像视图无法缩放到帧的问题。我在自定义视图中创建了一个自定义视图,我添加了imageview并为其父视图(此处为containerview)设置了约束

图像内容模式为 scaleAspectFit

let imageView = makeImageView()
addSubview(imageView)

imageView.topAnchor.constraint(equalTo: topAnchor).isActive = true
imageView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
imageView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

当我将自定义视图初始化到视图控制器中时,如上面的屏幕截图所示。在viewcontroller中,我只是将图像添加到stackview中。

你能告诉我应该添加什么吗?

iOS Swift 自动布局 UIImageView

评论

1赞 HangarRash 9/21/2023
你想看到什么不同的东西?橙色是图像视图。您告诉图像视图将图像显示为“纵横比拟合”。这正是它正在做的事情。
0赞 Arun 9/21/2023
@HangarRash,是的,你是对的。但是图像具有动态大小,应以纵横比显示(图像将显示为原始图像)。在这种情况下,我无法设置 aspectToFill 属性。那我怎样才能做到这一点呢?提前致谢。.
0赞 Arun 9/21/2023
@Naresh累了,但不工作。

答:

0赞 DonMag 9/22/2023 #1

您需要将图像视图的内容模式设置为 。.contentMode = .scaleToFill

然后,当您设置其 时,使用以下命令设置比例高度锚点:.image

multiplier: img.size.height / img.size.width)

下面是一个示例自定义类 - 为了清楚起见,我在所有 4 个侧面插入了 8 个点的图像视图:

class ProportionalImageView: UIView {
    
    public var image: UIImage? {
        didSet {
            imgView.image = image
            if let img = image {
                proConstraint.isActive = false
                proConstraint = imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor, multiplier: img.size.height / img.size.width)
                proConstraint.isActive = true
            }
        }
    }
    
    private var proConstraint: NSLayoutConstraint!
    
    private let imgView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    private func commonInit() {

        imgView.contentMode = .scaleToFill
        imgView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(imgView)
    
        proConstraint = imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor, multiplier: 1.0)
        
        NSLayoutConstraint.activate([
            imgView.topAnchor.constraint(equalTo: topAnchor, constant: 8.0),
            imgView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8.0),
            imgView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8.0),
            imgView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8.0),
            proConstraint,
        ])
        
        backgroundColor = .systemBlue
    }
    
}

以及一个示例视图控制器...垂直堆栈视图,包含“顶部标签”、自定义视图和“底部标签”。还加载 3 张图像 - 300x300、300x200 和 200x300。点击任意位置可循环到下一张图像:

class ProImageTestVC: UIViewController {
    
    let proImageView = ProportionalImageView()
    
    var images: [UIImage] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        ["i300x300", "i200x300", "i300x200"].forEach { sName in
            guard let img = UIImage(named: sName) else {
                fatalError("Could not load image: \(sName)")
            }
            images.append(img)
        }
        
        let stackView = UIStackView()
        stackView.axis = .vertical
    
        let v1 = UILabel()
        v1.text = "Top Label"
        v1.textAlignment = .center
        v1.backgroundColor = .green
        
        let v2 = UILabel()
        v2.text = "Bottom Label"
        v2.textAlignment = .center
        v2.backgroundColor = .green
        
        stackView.addArrangedSubview(v1)
        stackView.addArrangedSubview(proImageView)
        stackView.addArrangedSubview(v2)

        stackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stackView)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
            stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 60.0),
            stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -60.0),
        ])
        
        nextImage()
    }

    func nextImage() {
        let img = images.removeFirst()
        images.append(img)
        proImageView.image = img
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        nextImage()
    }
    
}

使用这三个图像:

enter image description here

enter image description here

enter image description here

运行时看起来像这样:

enter image description here

enter image description here

enter image description here