Issue with SFSymbol

Hi all,
I’m trying to make a lock screen widget for my car charge level and am using SFSymbols car.fill and bolt.car.fill to show the charge state. car.fill shows as I’d expect, but bolt.car.fill seems to be showing completely filled in. Is there something I’m missing or is this a bug?

Dan

Seems you’re doing this in Scriptable? Or some other app?

My bad I thought I tagged the post, yes it’s in Scriptable

1 Like

This behavior could be because of the widget settings. Odd things happen on Lock Screen.

What if you set:
w.addAccessoryWidgetBackground = true

Thanks for that, I’ve tried it but it doesn’t seem to affect how this icon shows. I thought it could be something to do with fonts but nothing I change seems to affect this :confused:

The issue is the symbol is rendering with colour and when tinted ends up all the same colour. Try toggling line 4:

let widget = new ListWidget()
let image = SFSymbol.named('bolt.car.fill').image
let sym = widget.addImage(image)
//sym.tintColor = Color.black()
widget.presentSmall()
Script.setWidget(widget)
Script.complete()

What seems to be missing is a way to choose the SF Symbol rendering mode (or in this case, to use monochrome with accessory widgets). Interestingly, this works on macOS (escaped unicode or even just pasting the character from the SF Symbols app) but maybe iOS doesn’t have the same font support:

let widget = new ListWidget()
widget.addText("\udbc1\udf43")
widget.presentSmall()
Script.setWidget(widget)
Script.complete()
1 Like

For fun, I played with one way of making it work: drawing the symbol myself. It’s not too hard because you can copy the image from the SF Symbols app and a quick find’n’replace on the SVG path will get you most of the way to this:

const s = 10 // scale factor
let context = new DrawContext()
context.opaque = false
context.size = new Size(24*s, 20*s)
let path = new Path()
// map SVG path commands to Path methods
const p = (x, y) => new Point(x*s+s/2, y*s+s/2)
const m = (x, y) => path.move(p(x, y))
const l = (x, y) => path.addLine(p(x, y))
const c = (x, y, cx, cy, dx, dy) => path.addCurve(p(dx, dy), p(cx, cy), p(x, y))
const z = () => path.closeSubpath()
// SVG path
m(16.875, 0.136719)
c(18.1738, 0.3125, 19.1797, 0.966797, 19.707, 2.07031)
c(20.0391, 2.79297, 20.6934, 4.63867, 21.0449, 6.39648)
l(21.875, 7.46094)
c(22.7734, 8.63281, 23.1055, 9.55078, 23.1055, 11.2012)
l(23.1055, 16.8262)
c(23.1055, 17.5488, 22.5488, 18.1152, 21.8164, 18.1152)
l(20.6641, 18.1152)
c(19.9316, 18.1152, 19.375, 17.5488, 19.375, 16.8262)
l(19.375, 15.1901)
c(17.213, 15.3324, 14.0651, 15.4297, 11.5527, 15.4297)
c(9.04264, 15.4297, 5.90391, 15.3325, 3.74023, 15.1905)
l(3.74023, 16.8262)
c(3.74023, 17.5488, 3.17383, 18.1152, 2.44141, 18.1152)
l(1.29883, 18.1152)
c(0.566406, 18.1152, 0, 17.5488, 0, 16.8262)
l(0, 11.2012)
c(0, 9.55078, 0.332031, 8.63281, 1.24023, 7.46094)
l(2.06055, 6.39648)
c(2.42188, 4.63867, 3.06641, 2.79297, 3.4082, 2.07031)
c(3.92578, 0.966797, 4.94141, 0.292969, 6.24023, 0.136719)
c(6.89453, 0.0585938, 9.0332, 0, 11.5527, 0)
c(14.082, 0, 16.2207, 0.0488281, 16.875, 0.136719)
z()
m(12.5293, 2.97852)
l(8.49609, 8.04688)
c(8.41797, 8.14453, 8.36914, 8.23242, 8.36914, 8.33984)
c(8.36914, 8.51562, 8.52539, 8.65234, 8.71094, 8.65234)
l(11.2109, 8.65234)
l(9.87305, 12.2266)
c(9.6875, 12.6953, 10.2051, 12.959, 10.5176, 12.5781)
l(14.5312, 7.50977)
c(14.6289, 7.42188, 14.6777, 7.31445, 14.6777, 7.2168)
c(14.6777, 7.04102, 14.5117, 6.89453, 14.3262, 6.89453)
l(11.8359, 6.89453)
l(13.1641, 3.33008)
c(13.3398, 2.85156, 12.832, 2.59766, 12.5293, 2.97852)
z()
context.addPath(path)
context.setFillColor(Color.dynamic(Color.black(), Color.white()))
context.fillPath()
let image = context.getImage()
let widget = new ListWidget()
widget.addImage(image)
widget.presentAccessoryInline()
Script.setWidget(widget)
Script.complete()
2 Likes

That’s worked perfectly, I didn’t even think about trying to draw it manually!

Thanks for your help! :slight_smile:

1 Like