在SwiftUI中更改SF Symbol图标的描边/填充颜色?

48

我正在寻找一种在SwiftUI中更改SF Symbol图标的描边/填充颜色的方法。

我尝试过.background(Color.red),但那只会改变整个图标的背景(实际图标本身没有改变),正如其含义。我还尝试了.foregroundColor(Color.red),但对图标没有影响。

内容视图的内容如下:

var body: some View {
    Image(systemName: "person.circle").foregroundColor(.red)    
}

2
Image(systemName: "person.circle").foregroundColor(.red) 为我绘制了一个红色的人物圆圈。它为你绘制了什么? - rob mayoff
对我来说,它仍然是一个黑色图标。可能只是Xcode的一个bug... 至少我希望是这样。 - Taylor Miller-Klugman
请发布一个小的、自包含的测试。创建一个新的SwiftUI项目,并修改默认的ContentView以演示问题。然后将ContentView的定义复制到您的问题中。 - rob mayoff
你是在运行代码还是使用预览?对我来说,预览显示的图标是黑色的,但运行它会正确地改变颜色。 - piebie
Image(systemName: "person.circle").foregroundColor(.red) 可以正常工作,但我想像 Image("clock").foregroundColor(.blue) 那样给自定义的标志上色,但它不起作用。 - Farras Doko
显示剩余2条评论
8个回答

51

您可以使用foregroundColor(_ color: Color?)更改 SF 符号图标的描边和填充颜色。

下面的代码:

Image(systemName: "flame.fill").foregroundColor(.red)
Image(systemName: "flame").foregroundColor(.red)

应产生此结果:

已填充和描边的Flame SF Symbol图标

这是完整的SwiftUI视图代码

struct Icon : View {
    var body: some View {
        HStack{
            Image(systemName: "flame.fill")
            .foregroundColor(.red)
            Image(systemName: "flame")
            .foregroundColor(.red)
        }
        .padding()
    }
}

太好了。foregroundColor 对我很有帮助。你可能会认为 accentColor 更能描述这个功能,但那个不起作用。 - Ramon
请注意,如果您使用Image(uiImage: UiImage("flame.fill")),则foregroundColor对图像没有影响。 - Thomas
SFSymbol的.fill.outline变体现在自动选择,具体取决于包含视图。例如,在Mac上的TabView中。Mac和iOS选项卡视图不会同时使用.fill - Pranav Kasetti
1
@Thomas,你可以通过设置渲染模式来解决无法使用UIImage源的foregroundColor问题,例如Image(uiImage: UiImage("flame.fill")).renderingMode(.template).foregroundColor(Color(.red))。我仍然有一些通过PaintCode生成的编程图标返回为UIImages。 - Kpalser

21

iOS 15

自 iOS 15 开始,使用 SFSymbols 3,您可以使用前景样式修饰符将不同层次的颜色应用于单个符号:

Image(systemName: "person.circle")
    .resizable()
    .foregroundStyle(.red, .blue)
    .frame(width: 200, height: 200, alignment: .center)

Demo 1


iOS 13和14

您可以使用ZStack来制作图标的不同部分,并对每一层应用不同的修饰符,例如:

///  I've used `GeometryReader ` for setting the size of elements dependent on each other

GeometryReader { proxy in 
    ZStack {
        Image(systemName: "circle")
            .resizable()
            .foregroundColor(.blue)

        Image(systemName: "person.fill")
            .resizable()
            .foregroundColor(.red)
            .frame(
                   width: proxy.size.width * 0.55,
                   height: proxy.size.width * 0.55,
                   alignment: .center
            )
    }
}.frame(width: 200, height: 200, alignment: .center)

Demo 2

请注意,旧方法和新方法看起来略有不同,但感觉相同。(仔细观察头的圆度)


不建议在使用.resizablesystemImage时,因为它会被转换成字体之外的其他东西。 - JAHelia

17

iOS 15及以上版本

在iOS 15中,我们可以使用foregroundStyle更加自定义SF Symbols:

Image(systemName: "cloud.sun.bolt")
    .foregroundStyle(.gray, .blue)

请参阅这个WWDC会话了解更多:

输入图像描述


4

我发现在iOS14中一个不错的技巧是使用填充和非填充版本一起使用,以获取两种颜色,无论是14还是15:

ZStack {
    Image(systemName: "person.circle")
        .foregroundColor(.white)
    Image(systemName: "person.circle.fill")
        .foregroundColor(.yellow)
}

2
有的,它就是"最初的回答"。
var body: some View {
    Image(systemName: "person.circle").accentColor(.red)    
}

3
这在早期测试版中可行。我认为目前正确的方法是使用.foregroundColor(.red)。 - Filip Sakel

1

SwiftUI现在允许您为许多SF Symbols的部分(图层)着色。一些符号有许多层。

这将使符号前景变为蓝色:

Image(systemName: "person.circle").foregroundStyle(.blue)

如果你想让圆形与人物颜色不同,那么这将使人物变成蓝色,圆形变成灰色。
Image(systemName: "person.circle").foregroundStyle(.blue, .gray)

0

这将以红色绘制图标的背景和蓝色绘制线条:

Image(systemName: "person.circle")
    .foregroundColor(Color.red)
    .background(Color.blue)
    .frame(width: size, height: self, alignment: .center)
    .clipShape(Circle())

如果没有clipShape,圆形背后的矩形会有蓝色的角落。


-1

只需更改色调颜色即可。这对我有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接