99 lines
2.8 KiB
Swift
99 lines
2.8 KiB
Swift
import ExpoModulesCore
|
|
|
|
class SymbolView: ExpoView {
|
|
let imageView = UIImageView()
|
|
|
|
// MARK: Properties
|
|
var name: String = ""
|
|
var weight: UIImage.SymbolWeight = .unspecified
|
|
var scale: UIImage.SymbolScale = .default
|
|
var imageContentMode: UIView.ContentMode = .scaleToFill
|
|
var symbolType: SymbolType = .monochrome
|
|
var tint: UIColor?
|
|
var animationSpec: AnimationSpec?
|
|
var palette = [UIColor]()
|
|
var animated = false
|
|
|
|
required init(appContext: AppContext? = nil) {
|
|
super.init(appContext: appContext)
|
|
addSubview(imageView)
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
imageView.frame = bounds
|
|
}
|
|
|
|
func reloadSymbol() {
|
|
guard let image = UIImage(systemName: name) else {
|
|
return
|
|
}
|
|
imageView.image = image
|
|
imageView.contentMode = imageContentMode
|
|
imageView.preferredSymbolConfiguration = getSymbolConfig()
|
|
|
|
if let tint {
|
|
if symbolType != .hierarchical {
|
|
imageView.image = image.withTintColor(tint, renderingMode: .alwaysOriginal)
|
|
}
|
|
}
|
|
|
|
// Effects need to be added last
|
|
if #available(iOS 17.0, tvOS 17.0, *) {
|
|
imageView.removeAllSymbolEffects()
|
|
if animated {
|
|
addSymbolEffects()
|
|
}
|
|
}
|
|
}
|
|
|
|
@available(iOS 17.0, tvOS 17.0, *)
|
|
private func addSymbolEffects() {
|
|
if let animationSpec {
|
|
let repeating = animationSpec.repeating ?? false
|
|
var options: SymbolEffectOptions = repeating ? .repeating : .nonRepeating
|
|
|
|
if let repeatCount = animationSpec.repeatCount {
|
|
options = options.repeat(abs(repeatCount))
|
|
}
|
|
|
|
if let speed = animationSpec.speed {
|
|
options = options.speed(speed)
|
|
}
|
|
|
|
if let variableAnimationSpec = animationSpec.variableAnimationSpec {
|
|
imageView.addSymbolEffect(variableAnimationSpec.toVariableEffect())
|
|
return
|
|
}
|
|
|
|
if let animation = animationSpec.effect {
|
|
animation.toEffect().add(to: imageView, with: options)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func getSymbolConfig() -> UIImage.SymbolConfiguration {
|
|
#if os(tvOS)
|
|
var config = UIImage.SymbolConfiguration(pointSize: 18.0, weight: weight, scale: scale)
|
|
#else
|
|
var config = UIImage.SymbolConfiguration(pointSize: UIFont.systemFontSize, weight: weight, scale: scale)
|
|
#endif
|
|
|
|
switch symbolType {
|
|
case .monochrome:
|
|
if #available(iOS 16.0, tvOS 16.0, *) {
|
|
config = config.applying(UIImage.SymbolConfiguration.preferringMonochrome())
|
|
}
|
|
case .hierarchical:
|
|
config = config.applying(UIImage.SymbolConfiguration(hierarchicalColor: tint ?? .systemBlue))
|
|
case .palette:
|
|
if palette.count > 1 {
|
|
config = config.applying(UIImage.SymbolConfiguration(paletteColors: palette))
|
|
}
|
|
case .multicolor:
|
|
config = config.applying(UIImage.SymbolConfiguration.preferringMulticolor())
|
|
}
|
|
|
|
return config
|
|
}
|
|
}
|