Let's think about it this way for a second
You can call a custom image from `Assets.xcassets` with `Image("logo")` — auto-selection by device resolution (1x/2x/3x) is included. SF Symbols, on the other hand, is Apple's own icon library (over 5,000 icons) — calling `Image(systemName: "heart.fill")` gets you an icon with automatic dark mode/accessibility (Dynamic Type) support, no custom asset needed.
Let's connect this to a real-world scenario
On a like button, if you write `Image(systemName: isLiked ? "heart.fill" : "heart")` — the icon switches between filled and outline based on state, with no custom asset needed at all. Adding `accessibilityLabel("Like this post")` gives you support for VoiceOver (screen reader).
Let's look at it together
struct LikeButton: View {
@State private var isLiked = false
var body: some View {
Button {
isLiked.toggle()
} label: {
Image(systemName: isLiked ? "heart.fill" : "heart")
.foregroundColor(isLiked ? .red : .gray)
}
.accessibilityLabel(isLiked ? "Unlike this post" : "Like this post")
}
}Every time you tap the button, you'll see the heart icon toggle between outline and filled.5-minute try-it
Run `LikeButton` and try tapping it — then open the SF Symbols app (a browser tool Apple provides on Mac) and search for a new icon name.
A quick heads-up
Dropping an unoptimized custom image (a high-resolution photo) straight into `Assets.xcassets` bloats your app size and can hurt App Store download/install time.