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

如何通过SwiftUI Image显示带SFSymbol的UIImage?

问题:通过UIImage加载SF Symbol无法渲染的解决方案

问题描述

我有一个只能传入UIImage对象的Image组件,现在需要在其中显示SF Symbol。尝试用带systemName的UIImage实现,但代码无法渲染出图像:

struct ContentView: View {
    var body: some View {
        VStack {
            Image(uiImage: UIImage(systemName: "airplane.circle.fill")!.withRenderingMode(.alwaysOriginal))
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 150, height: 150)
        }
        .background {
            Color.black.ignoresSafeArea()
        }
    }
}

已知可以直接使用Image的systemName初始化器,但受限于现有约束无法采用,求可行实现方案。

可行方案

问题根源在于withRenderingMode(.alwaysOriginal)的误用:SF Symbol默认是模板模式(Template),当强制设置为alwaysOriginal时,若未显式指定颜色,在黑色背景上会因默认颜色与背景一致而无法显示。

方法1:保留模板模式,通过SwiftUI着色

移除withRenderingMode(.alwaysOriginal),改用SwiftUI的foregroundColor指定符号颜色,让UIImage保持模板模式,SwiftUI可正常着色:

struct ContentView: View {
    var body: some View {
        VStack {
            Image(uiImage: UIImage(systemName: "airplane.circle.fill")!)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 150, height: 150)
                .foregroundColor(.white) // 显式设置符号颜色
        }
        .background {
            Color.black.ignoresSafeArea()
        }
    }
}

方法2:提前给UIImage添加颜色(适配无法用SwiftUI着色的场景)

如果自定义组件不支持SwiftUI的foregroundColor,可以通过Core Graphics给UIImage预设置颜色,再设置为alwaysOriginal:

extension UIImage {
    func tinted(with color: UIColor) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        defer { UIGraphicsEndImageContext() }
        
        color.setFill()
        draw(in: CGRect(origin: .zero, size: size))
        
        return UIGraphicsGetImageFromCurrentImageContext()?.withRenderingMode(.alwaysOriginal)
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            if let tintedSymbol = UIImage(systemName: "airplane.circle.fill")?.tinted(with: .white) {
                Image(uiImage: tintedSymbol)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 150, height: 150)
            }
        }
        .background {
            Color.black.ignoresSafeArea()
        }
    }
}

内容的提问来源于stack exchange,提问作者batman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:22:09