ios 是否可以在UIImageView中结合使用aspect fill内容模式和top内容模式?

kpbpu008  于 2023-04-22  发布在  iOS
关注(0)|答案(6)|浏览(176)

对于一个UIImageView,我使用的是aspect fill内容模式。这是可以的,但是对于一些图像,它会从顶部剪切,因为我使用了clipsToBounds = true。所以下面是我想要的:我想同时激活两个过滤器,例如:
下面是我设置为aspect fill的图像视图:

...以及我使用contentMode = .top设置的图像视图:

所以我想合并这两种内容模式。这是可能的吗?提前感谢。

rslzwgfq

rslzwgfq1#

**更新:**设备扩展现在可以正确处理,感谢budidino

您应该调整图像的大小,使其具有图像视图的宽度,但保持其纵横比。之后,将图像视图的内容模式设置为.top,并启用剪裁到边界。
resizeTopAlignedToFill函数是this answer的修改版本。

func setImageView() {
    imageView.contentMode = .top
    imageView.clipsToBounds = true

    let image = <custom image>
    imageView.image = image.resizeTopAlignedToFill(newWidth: imageView.frame.width)
}

extension UIImage {
    func resizeTopAlignedToFill(newWidth: CGFloat) -> UIImage? {
        let newHeight = size.height * newWidth / size.width

        let newSize = CGSize(width: newWidth, height: newHeight)

        UIGraphicsBeginImageContextWithOptions(newSize, false, UIScreen.main.scale)
        draw(in: CGRect(origin: .zero, size: newSize))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage
    }
}
pepwfjgg

pepwfjgg2#

试试这个:

imageView.contentMode = UIViewContentModeTop;
imageView.image = [UIImage imageWithCGImage:image.CGImage scale:image.size.width / imageView.frame.size.width orientation:UIImageOrientationUp];
lyr7nygr

lyr7nygr3#

这是我的解决方案。首先,你将comtentMode设置为top,然后调整图片大小

func resize(toWidth scaledToWidth: CGFloat) -> UIImage {
        let image = self
        let oldWidth = image.size.width
        let scaleFactor = scaledToWidth / oldWidth
        let newHeight = image.size.height * scaleFactor
        let newWidth = oldWidth * scaleFactor
        let scaledSize = CGSize(width:newWidth, height:newHeight)
        UIGraphicsBeginImageContextWithOptions(scaledSize, false, 0)
        image.draw(in: CGRect(x: 0, y: 0, width: scaledSize.width, height: scaledSize.height))
        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return scaledImage!
    }

imageView.contentMode = .top
imageView.image = imageView.resize(toWidth:imageView.frame.width)
xnifntxz

xnifntxz4#

公认的答案是缩小图像,从而降低@2x和@3x设备上的质量。这应该会产生相同的结果,但图像质量更好:

extension UIImage {
  func resizeTopAlignedToFill(containerSize: CGSize) -> UIImage? {
    let scaleTarget = containerSize.height / containerSize.width
    let scaleOriginal = size.height / size.width

    if scaleOriginal <= scaleTarget { return self }

    let newHeight = size.width * scaleTarget
    let newSize = CGSize(width: size.width, height: newHeight)

    UIGraphicsBeginImageContextWithOptions(newSize, false, scale)
    self.draw(in: CGRect(origin: .zero, size: newSize))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
  }
}

然后使用它:

imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.image = UIImage(named: "portrait").resizeTopAlignedToFill(containerSize: imageView.frame.size)
0yg35tkg

0yg35tkg5#

考虑到性能问题,我建议将具有完整图像大小/宽高比的UIImageView放入clipsToBounds设置为true的ContainerView中。

brgchamk

brgchamk6#

Swift 5:

imageView.contentMode = .top
if let image = UIImage(named: "xxx"),
   let cgImage = image.cgImage {
    imageView.image = UIImage(cgImage: cgImage, scale: image.size.width / view.frame.size.width * UIScreen.main.scale, orientation: .up)
}

相关问题