sf_symbols 0.5.0 copy "sf_symbols: ^0.5.0" to clipboard
sf_symbols: ^0.5.0 copied to clipboard

Use SF Symbols on iOS, same as Image(systemName:) or UIImage(systemName:) in Swift.

sf_symbols #

The example app, showing symbol weights, scales, the four rendering modes, variable values and animated effects

Use SF Symbols on iOS, the same way you would use Image(systemName:) or UIImage(systemName:) in Swift.

Requirements #

Flutter 3.27 or newer
iOS 15.0 or newer
Build system Swift Package Manager or CocoaPods

iOS only. On other platforms the widget draws nothing instead of failing, so it is safe to leave in a cross-platform tree — SfSymbol.isAvailable answers false there, and SfSymbol.effectSupport answers none.

Usage #

Use SfSymbol like any other widget, with a name, weight, color and size.

size is the pointSize of UIImage.SymbolConfiguration, so a symbol of size 40 renders roughly 40 x 40 logical pixels — the widget sizes itself to whatever iOS actually draws, which is rarely exactly square.

SfSymbol(
    name: 'camera.aperture',
    weight: FontWeight.w900,
    color: Colors.pink,
    size: 40,
)

Names come from the SF Symbols app. If a name does not exist on the running iOS version, the widget renders nothing rather than throwing. Check first with await SfSymbol.isAvailable('camera.macro') if you want to fall back to something else.

The widget re-renders whenever its properties change, so a symbol can be tinted on press or swapped out as state changes.

Rendering modes #

SF Symbols draw in four modes. Each has its own constructor:

// One flat color.
SfSymbol(name: 'cloud.sun.rain.fill', color: Colors.blue, size: 40)

// One color, applied at several opacities across the symbol's layers.
SfSymbol.hierarchical(name: 'cloud.sun.rain.fill', color: Colors.blue, size: 40)

// Up to three colors, assigned to the layers in order.
SfSymbol.palette(
  name: 'cloud.sun.rain.fill',
  colors: [Colors.pink, Colors.amber, Colors.cyan],
  size: 40,
)

// The symbol's own colors. `color` tints symbols that have no multicolor variant.
SfSymbol.multicolor(name: 'cloud.sun.rain.fill', color: Colors.blue, size: 40)

Variable symbols #

Symbols such as wifi, speaker.wave.3 and battery.100 draw a fill level from variableValue, between 0.0 and 1.0. Requires iOS 16; earlier versions draw the symbol full.

SfSymbol(name: 'wifi', color: Colors.blue, size: 40, variableValue: 0.45)

Scale and accessibility #

scale maps to UIImage.SymbolScale, sizing the symbol relative to its point size. semanticLabel describes the symbol to VoiceOver.

SfSymbol(
  name: 'camera',
  color: Colors.blue,
  size: 40,
  scale: SfSymbolScale.large,
  semanticLabel: 'Camera',
)

Effects #

Symbols can play the SF Symbols animations. Pass an effect:

SfSymbol(
  name: 'wifi.router.fill',
  color: Colors.blue,
  size: 40,
  effect: SfSymbolEffect.variableColor,
)

bounce, pulse, variableColor and scale need iOS 17; wiggle, rotate and breathe need iOS 18. Asking for an effect the running iOS cannot play leaves the symbol still rather than failing, so no version check is required. await SfSymbol.effectSupport() reports what the device can play if you want to choose a different effect or hide a control.

effectRepeats: false plays the effect once instead of looping. That only applies to the effects that have a natural end — bounce, and one cycle of variableColor. pulse, wiggle, rotate and breathe run for as long as the symbol is on screen, and scale holds the symbol at its new size.

Animated symbols are redrawn every frame, so use them for the few symbols the user is meant to look at, not for every icon on the screen.

Caching #

Identical symbols share one native texture, so a list of a hundred rows showing the same icon costs one rendered image rather than a hundred. A symbol that is already rendered draws on its first frame, with no blank gap while the platform channel answers.

Symbols scrolled off screen are kept for a while in case they come back. To render one before it is first shown:

await SfSymbol.precache(
  const SfSymbolConfig(name: 'camera', size: 40, colors: [Colors.blue]),
);

The config has to match the one the widget asks for, down to the size and the weight, or the two are different images. someSymbol.config gives you the config of an SfSymbol you already have.

SfSymbolCache.instance exposes maximumUnusedEntries (48 by default) and evictUnused() for apps that want to tune the off-screen pool or drop it under memory pressure. Animated symbols are never pooled: keeping one alive would keep its display link running.

How it works #

iOS renders the symbol into a pixel buffer, which Flutter draws as a Texture. The symbols are the real ones from the system, at whatever version of the SF Symbols set the device ships, and an animated symbol is a UIKit symbol effect with its frames pushed into the texture.

Running the example #

cd example
flutter run -d <ios simulator or device>

The end-to-end tests exercise the native side and need a real simulator or device:

cd example
flutter test integration_test -d <ios simulator or device>

Roadmap #

  • Support for macOS
14
likes
0
points
1.12k
downloads

Publisher

verified publisherhanshi.tech

Weekly Downloads

Use SF Symbols on iOS, same as Image(systemName:) or UIImage(systemName:) in Swift.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on sf_symbols

Packages that implement sf_symbols