如何在uiimageview内部向右移动uiimage的同时保留原始图像的长宽比?

问题描述

当用户使用uiimagepicker导入图像时,我想将图像向右移动,但是当我将内容模式设置为.right时,发生这种情况:The image enlarges for some reason and it looks like it moves to the left

有什么方法可以保持uiimageview的宽高比和导入的图像的宽高比,同时还可以将其移到图像视图的右侧。

This is how I want it to be

解决方法

这是一种方法:使用子图层将内容设置为图像的自定义视图...

  • 添加一个CALayer作为子层
  • 计算视图范围内图像的长宽比例矩形
  • 将图像层的帧设置为缩放后的矩形
  • 然后根据所需的对齐方式设置图层的原点

一个简单的例子:

class AspectAlignImageView: UIView {
    
    enum AspectAlign {
        case top,left,right,bottom,center
    }
    
    // this is an array so we can set two options
    //  if,for example,we don't know if the image will be
    //  taller or narrower
    //  for example:
    //      [.top,.right] will put a
    //          wide image aligned top
    //          narrow image aligned right
    public var alignment: [AspectAlign] = [.center]
    public var image: UIImage?
    
    private let imgLayer: CALayer = CALayer()
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        // make sure we have an image
        if let img = image {
            // only add the sublayer once
            if imgLayer.superlayer == nil {
                layer.addSublayer(imgLayer)
            }
            imgLayer.contentsGravity = .resize
            imgLayer.contents = img.cgImage

            // calculate the aspect-scaled rect inside our bounds
            var scaledImageRect = CGRect.zero
            let aspectWidth:CGFloat = bounds.width / img.size.width
            let aspectHeight:CGFloat = bounds.height / img.size.height
            let aspectRatio:CGFloat = min(aspectWidth,aspectHeight)
            scaledImageRect.size.width = img.size.width * aspectRatio
            scaledImageRect.size.height = img.size.height * aspectRatio

            // set image layer frame to aspect-scaled rect
            imgLayer.frame = scaledImageRect
            
            // align as specified
            if alignment.contains(.top) {
                imgLayer.frame.origin.y = 0
            }
            if alignment.contains(.left) {
                imgLayer.frame.origin.x = 0
            }
            if alignment.contains(.bottom) {
                imgLayer.frame.origin.y = bounds.maxY - scaledImageRect.height
            }
            if alignment.contains(.right) {
                imgLayer.frame.origin.x = bounds.maxX - scaledImageRect.width
            }
        }
    }
    
}

class TestAlignViewController: UIViewController {

    let testView = AspectAlignImageView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        testView.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(testView)
        
        NSLayoutConstraint.activate([
            // constrain test view 240x240 square
            testView.widthAnchor.constraint(equalToConstant: 240.0),testView.heightAnchor.constraint(equalTo: testView.widthAnchor),// centered in view
            testView.centerXAnchor.constraint(equalTo: view.centerXAnchor),testView.centerYAnchor.constraint(equalTo: view.centerYAnchor),])
        
        if let img = UIImage(named: "bottle") {
            testView.image = img
        }
        testView.alignment = [.right]
    
        // so we can see the actual view frame
        testView.backgroundColor = .green
    }
    
}

使用此图像:

enter image description here

在240x240的视图中(视图背景设置为绿色,因此我们可以看到其框架),我们得到以下结果:

enter image description here

,

将UIImage内容模式设置为宽高比填充或宽高比适合。然后使用自动布局。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...