SFSafeSymbols / SFSafeSymbols

Safely access Apple's SF Symbols using static typing

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Supporting custom SFSymbols

ramink opened this issue · comments

commented

This looks like a great and useful project. I'm going to try to use it in a personal project.

Looking ahead, though, I can see myself making my own custom additions to SF Symbols. I haven't tried this yet, but Apple documents how you would do this. Does SFSafeSymbols already give us a way to extend its support to our own custom additions?

Hi @ramink,

yes, that's possible (and we should probably document it in the README.md, right, @StevenSorial?)

Works like this:

public extension SFSymbol {
    // My custom symbol
    static let myCustomSymbol = SFSymbol(rawValue: "my_custom_symbol_key")
}

Let me know if this answer helps you :)

I think you have to use the name rather than systemName initializers for custom symbols, so that might not work.

commented

Hi @fredpi, @j-f1 ,

Thanks for the replies. I think I understand what you're saying. Yes, if either variant works, it would satisfy my needs.

Here I was, thinking SFSymbol was an enum, and I thought we were in a bind. But all along it was a class with many Type Properties. Nice!

Hi @ramink,

I gave a more detailed answer to this question here and here.

commented

Thanks. I chased this down a bit, and I see why it's not entirely straightforward.

But thinking about it, it seems like using subclasses might give us something worth considering. For instance, you could have:

public class SFSystemSymbol: SFSymbol { }
public class SFCustomSymbol: SFSymbol { }

// In the shipping extensions you would use SFSystemSymbol:
extension SFSymbol {
static let _1Lane = SFSystemSymbol(rawValue: "1.lane")
}

// While we would add support for our custom symbols in our own extensions using SFCustomSymbol:
extension SFSymbol {
static let git = SFCustomSymbol(rawValue: "git")
}

// And then they they could be picked up by different initialisers automatically if they are written like this:

public extension SwiftUI.Image {
     init(systemSymbol: SFSystemSymbol) {
        self.init(systemName: systemSymbol.rawValue)
    }

     init(systemSymbol: SFCustomSymbol) {
        self.init(named: systemSymbol.rawValue)
    }
}

Might something like that work? I think it wouldn't entail too many changes to the package.

You could do something like this:

public extension Image {
  struct Name {
    let rawValue: String
    static let git = Self(rawValue: "git")
  }

  init(_ name: Name) {
    self.init(named: name.rawValue)
  }

  // usage: Image(.git)
}

To be honest, I think this better solved by a code generation tool for assets like SwiftGen or R.Swift.
UIKit and SwiftUI use the same initializers for normal image assets, so its easier to just use the existing tools for that.

commented

OK. Thanks for considering it. I don't know about SwiftGen and R.Swift, so I'll see if they suit my needs. Thanks for the pointers!