You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:25:30