Swift中如何实现IBDesignable图片降采样功能?
问题:UIImageView扩展实现降采样无效,自定义类却可行?
运行应用时遇到图片内存占用过高问题:一张905kb的SVG图片加载后占用约150MB内存,且会被系统缓存,多页面加载不同SVG图片会引发内存压力。
已实现基于图片尺寸的降采样功能,当前通过将UIImageView的自定义类设为DownsamplingImageView即可启用该功能,降采样后内存占用从150MB降至6MB,页面退出时内存也会正常释放。但希望创建UIImageView的IBDesignable扩展,无需替换自定义类就能实现降采样。
可用的降采样自定义类代码
import UIKit class DownsamplingImageView: UIImageView { @IBInspectable var downSample: Bool = true { didSet { setNeedsLayout() } } override func layoutSubviews() { super.layoutSubviews() if downSample, let image = self.image { let targetSize = self.bounds.size let downsampledImage = image.downsample(to: targetSize) self.image = downsampledImage } } } extension UIImage { func downsample(to targetSize: CGSize) -> UIImage? { let sourceSize = self.size let widthRatio = targetSize.width / sourceSize.width let heightRatio = targetSize.height / sourceSize.height let scaleFactor = max(widthRatio, heightRatio) let scaledSize = CGSize(width: sourceSize.width * scaleFactor, height: sourceSize.height * scaleFactor) UIGraphicsBeginImageContextWithOptions(scaledSize, false, 0.0) self.draw(in: CGRect(origin: CGPoint.zero, size: scaledSize)) let downsampledImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return downsampledImage } }
尝试编写但无效的UIImageView扩展代码
import UIKit @IBDesignable extension UIImageView { @IBInspectable var downSample: Bool { get { return image != nil } set { setNeedsLayout() } } override open func layoutSubviews() { super.layoutSubviews() if downSample, let image = self.image { let targetSize = self.bounds.size let downsampledImage = image.downsample(to: targetSize) self.image = downsampledImage } } } extension UIImage { func downsample(to targetSize: CGSize) -> UIImage? { let sourceSize = self.size let widthRatio = targetSize.width / sourceSize.width let heightRatio = targetSize.height / sourceSize.height let scaleFactor = max(widthRatio, heightRatio) let scaledSize = CGSize(width: sourceSize.width * scaleFactor, height: sourceSize.height * scaleFactor) UIGraphicsBeginImageContextWithOptions(scaledSize, false, 0.0) self.draw(in: CGRect(origin: CGPoint.zero, size: scaledSize)) let downsampledImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return downsampledImage } }
疑问
- 为何自定义类可行但扩展无效?
- 是否有办法让该扩展生效?
PS:降采样后内存占用从150MB降至6MB,且页面退出时内存会被释放。若需启用降采样,将UIImageView的自定义类设为DownsamplingImageView即可。
内容的提问来源于stack exchange,提问作者Zyfe3r
相关产品推荐
相关产品推荐

