对于一个UIImageView,我使用的是aspect fill内容模式。这是可以的,但是对于一些图像,它会从顶部剪切,因为我使用了clipsToBounds = true。所以下面是我想要的:我想同时激活两个过滤器,例如:下面是我设置为aspect fill的图像视图:
UIImageView
clipsToBounds = true
...以及我使用contentMode = .top设置的图像视图:
contentMode = .top
所以我想合并这两种内容模式。这是可能的吗?提前感谢。
rslzwgfq1#
**更新:**设备扩展现在可以正确处理,感谢budidino!
您应该调整图像的大小,使其具有图像视图的宽度,但保持其纵横比。之后,将图像视图的内容模式设置为.top,并启用剪裁到边界。resizeTopAlignedToFill函数是this answer的修改版本。
.top
resizeTopAlignedToFill
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 } }
pepwfjgg2#
试试这个:
imageView.contentMode = UIViewContentModeTop; imageView.image = [UIImage imageWithCGImage:image.CGImage scale:image.size.width / imageView.frame.size.width orientation:UIImageOrientationUp];
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)
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)
0yg35tkg5#
考虑到性能问题,我建议将具有完整图像大小/宽高比的UIImageView放入clipsToBounds设置为true的ContainerView中。
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) }
6条答案
按热度按时间rslzwgfq1#
**更新:**设备扩展现在可以正确处理,感谢budidino!
您应该调整图像的大小,使其具有图像视图的宽度,但保持其纵横比。之后,将图像视图的内容模式设置为
.top
,并启用剪裁到边界。resizeTopAlignedToFill
函数是this answer的修改版本。pepwfjgg2#
试试这个:
lyr7nygr3#
这是我的解决方案。首先,你将comtentMode设置为top,然后调整图片大小
xnifntxz4#
公认的答案是缩小图像,从而降低@2x和@3x设备上的质量。这应该会产生相同的结果,但图像质量更好:
然后使用它:
0yg35tkg5#
考虑到性能问题,我建议将具有完整图像大小/宽高比的UIImageView放入clipsToBounds设置为true的ContainerView中。
brgchamk6#
Swift 5: