7

I am trying to change the color of clear(transparent) part inside of a SF Symbol called delete.left.fill. So far I've tried is as follows

Button(action: { return }, label: {
                        Image(systemName: "delete.left.fill")
                            .background(Color.black)
                            //.accentColor(.black)
                            .font(.system(size: self.fontSize*0.75))
                    })
                        .frame(width: self.width, height: self.width)
                        .foregroundColor(.lightGray)
                        //.background(Color.black)

When I run the code as above, the result is like

symbol.

At first, the xinside of the symbol was the same color as background. I want it to make black.

  1. I tried to set the backgroundColor of the Button and it made whole Button black.
  2. I tried to set accentColor of the Image to black. Nothing changed.
  3. I tried to set backgroundColor of the Image to black. The result can be seen in the image.

The question is, is there a way to make just that x, inside the symbol, black programmatically?

Faruk
  • 2,269
  • 31
  • 42

3 Answers3

6

You could mask the background and apply a custom style:

struct MyButtonStyle: ButtonStyle {
  public func makeBody(configuration: MyButtonStyle.Configuration) -> some View {
    configuration.label
      .compositingGroup()
      .opacity(configuration.isPressed ? 0.5 : 1.0)
  }
}

Button(action: {}) {
  Image(systemName: "delete.left.fill")
    .foregroundColor(.green)
    .background(
      Color.black.mask(Circle())
    )
}.buttonStyle(MyButtonStyle())

The circle may not fit to any usage, but for this image it works okay:

enter image description here

nine stones
  • 3,264
  • 1
  • 24
  • 36
  • one more question though, it works but when I tap the button effect is working but there is a gray circle behind it and black parts fades to white more than it should do. Any suggestions on that? – Faruk Feb 01 '20 at 10:00
  • Yeah. that's ugly. Sorry for missing out. I update my answer. Now the button should behave nicely when tapped – nine stones Feb 01 '20 at 17:24
  • and the oscar goes to you. yet, how does this `compositonGroup()` works? – Faruk Feb 02 '20 at 13:14
  • @Faruk It treats subviews/modifiers as one before applying the modifier. in this case the views of `label` (= image, foreground, background and color) – nine stones Feb 02 '20 at 17:54
  • Altogether prolly still not the best solution. A better way could be to re-render the image filling all internally clear-color masked pixels with the color you want. But I didn't have the time to get into that. – nine stones Feb 02 '20 at 17:56
  • Well that is enough for me now. If you have the chance for update, it would be appreciated. Thanks for your help. – Faruk Feb 02 '20 at 23:34
5

as of iOS 15 you can simply achieve that with .foregroundStyle(.red, .blue)

JAHelia
  • 6,934
  • 17
  • 74
  • 134
3

As he warned with the circle, @Faruk's solution didn't work for me with the exclamationmark.triangle.fill

I created a ZStack with the fill and unfill versions to create a yellow triangle with a black exclamation point and a black border:

ZStack{
  Image(systemName: "exclamationmark.triangle")
    .foregroundColor(Color.black)
    .scaleEffect(1.1)
  Image(systemName: "exclamationmark.triangle.fill")
    .foregroundColor(Color.yellow)
}

I've only tried on couple of simulators, but it looks nice on iPadPro and iPad Mini