Is there a way to create symbols with dynamic text?

100 views Asked by At

I want to create a symbol that consists of the frame of a calendar and the number of the current day in the middle.

A symbol like that can be found on the today card in Apples Reminders app.

I couldn't find the symbol in SF Symbols.

But I found that there are symbols with dynamic text, e.g., if you search for "42.circle" you get a circle with the number 42 in it.

The question is, is there a stock symbol that achieves that? If not, how can I create symbols with dynamic text?

2

There are 2 answers

0
Benzy Neez On

If it doesn't have to be an Image then you can just apply an overlay to a blank symbol. For example:

private func calendarDay(day: Int) -> some View {
    Image(systemName: "note")
        .resizable()
        .scaledToFit()
        .overlay {
            Text("\(day)")
                .alignmentGuide(VerticalAlignment.center) { d in
                    d.height / 3
                }
        }
}
var body: some View {
    HStack(spacing: 50) {
        calendarDay(day: 18)
            .frame(width: 100, height: 100)
            .font(.largeTitle)
            .foregroundColor(.blue)
        calendarDay(day: 23)
            .frame(width: 30, height: 30)
            .font(.subheadline)
            .foregroundColor(.purple)
    }
}

Dates

0
soundflix On

You can generate the symbol name like this:

struct CalendarDay: View {
    var day: Int
    var fill: Bool = false
    var shape: SymbolShape = .circle
    
    enum SymbolShape: String {
        case circle = "circle"
        case square = "square"
    }
    
    private func calendarDay(day: Int, fill: Bool = false, shape: SymbolShape) -> String {
        var dayString: String
        if (1 ... 31).contains(day) {
            dayString = String(day)
        } else {
            dayString = "questionmark"
        }
        return "\(dayString).\(shape)\(fill ? ".fill" : "")"
    }
    
    var body: some View {
        Image(systemName: calendarDay(day: day, fill: fill, shape: shape))
            .resizable()
            .scaledToFit()
    }
}

example usage:

struct ContentView: View {
    var body: some View {
        VStack {
            HStack {
                CalendarDay(day: 03)
                    .foregroundColor(.red)
                    .padding()
                CalendarDay(day: 18, fill: true)
                    .foregroundColor(.blue)
                    .padding()
            }
            HStack {
                CalendarDay(day: 31, shape: .square)
                    .foregroundColor(.yellow)
                    .padding()
                CalendarDay(day: 42, fill: true, shape: .square)
                    .foregroundColor(.green)
                    .padding()
            }
        }
    }
}

enter image description here