Emoji Picker
A standalone SwiftUI emoji picker with keyword search, categories, and SF Symbol support
iOS doesn't ship a standalone emoji picker for developers. This reusable component provides categorised browsing, keyword search via a 20,000+ entry JSON dictionary, and a clean sheet-based UI. Includes two variants: a pure emoji picker (from Shopa) and an extended version with SF Symbols and colour tinting (from Writa).
Overview
iOS doesn't ship a standalone emoji picker that developers can embed in their own views. This reusable component provides a complete emoji selection experience with categorised browsing, keyword search via a JSON dictionary, and a clean SwiftUI interface. Originally built for Shopa, it was later extended in Writa to include SF Symbols and colour tinting for workspace icons.
Two Variants
Emoji-Only Picker
Pure emoji selection with 9 categories, keyword search, and a sheet presentation. Drop-in ready for any SwiftUI app.
Emoji + Symbols Picker
Extended version with a Symbols/Emoji tab switcher, SF Symbol grid, colour tinting, and cross-platform (iOS + macOS) support.
Variant 1: Emoji-Only Picker
Complete, self-contained picker from Shopa. Single file, no external dependencies beyond the optional keyword JSON. Copy and paste into your Xcode project.
Full emoji picker with 9 categories, keyword search, and sheet presentation
Variant 2: Emoji + Symbols Picker
Extended version from Writa with SF Symbols tab, colour picker, and cross-platform (iOS + macOS) support. Requires all three files below.
Main picker with Symbols/Emoji tabs, colour tinting, and cross-platform layout
Helper extension to detect emoji vs SF Symbol strings
Rendering helper for the live icon preview
Features
- 1.9 emoji categories — Smileys, People, Animals, Food, Activity, Travel, Objects, Symbols, and Flags with SF Symbol category icons
- 2.Keyword search — Loads a JSON dictionary of 20,000+ emoji keywords for accurate fuzzy search across all categories
- 3.LazyVGrid layout — 7–8 column grid with pinned section headers and smooth scroll-to-category navigation
- 4.Sheet presentation — Uses
.presentationDetentsfor half and full sheet sizes with drag indicator - 5.SF Symbols grid (Variant 2) — 9 symbol categories with colour tinting and live preview
- 6.Cross-platform (Variant 2) — Adapts layout for iOS (NavigationStack + searchable) and macOS (inline search field)
Quick Start
Drop in the code below and present it as a sheet. You'll also need the Emoji en US.json keywords file in your bundle for search to work (or remove the keyword search to use category-only browsing).
// Variant 1: Emoji-only picker
struct MyView: View {
@State private var selectedEmoji = "😀"
@State private var showPicker = false
var body: some View {
Button(selectedEmoji) {
showPicker = true
}
.font(.largeTitle)
.sheet(isPresented: $showPicker) {
EmojiPicker(selectedEmoji: $selectedEmoji)
}
}
}
// Variant 2: Emoji + Symbols picker (with colour)
struct WorkspaceSettingsView: View {
@State private var icon = "folder"
@State private var color = "systemBlue"
@State private var showPicker = false
var body: some View {
Button {
showPicker = true
} label: {
// Show emoji or SF Symbol based on selection
if icon.isEmojiIcon {
Text(icon).font(.largeTitle)
} else {
Image(systemName: icon)
.font(.largeTitle)
.foregroundStyle(Color(color))
}
}
.sheet(isPresented: $showPicker) {
WorkspaceIconPicker(selectedIcon: $icon, selectedColor: $color)
}
}
}Customisation
Change the grid columns
Modify the columns array count. The default is 7-8 columns. For larger emoji, try 5-6.
Remove keyword search
If you don't want to bundle the JSON, remove the keywordDictionary property and simplify searchAll() to only match category names.
Add/remove categories or emoji
Edit the EmojiData.categories array. Each category has a name, SF Symbol icon, and an array of emoji strings. Add new emoji as they become available in Unicode.
Add colour options
The Variant 2 includes IconColorOption with 9 system colours. Add or remove options from the options array.