Back to Experiments

Emoji Picker

A standalone SwiftUI emoji picker with keyword search, categories, and SF Symbol support

SwiftUIiOSmacOSReusable Component5 min
Search emojis
😊
👋
🐾
🍔
🚗
😀
😍
🤩
😎
🥳
😇
🤗
😏
👋
✌️
🤞
👍
👏
🙌
🤝
🐶
🐱
🦊
🐻
🐼
🐨
🦁
🐯
🍎
🍊
🍋
🍌
🍉
🍇
🍓
🍑

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.

Used in: Shopa
🎨

Emoji + Symbols Picker

Extended version with a Symbols/Emoji tab switcher, SF Symbol grid, colour tinting, and cross-platform (iOS + macOS) support.

Used in: Writa

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.

EmojiPicker.swiftSwift

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.

WorkspaceIconPicker.swiftSwift

Main picker with Symbols/Emoji tabs, colour tinting, and cross-platform layout

String+Emoji.swiftSwift

Helper extension to detect emoji vs SF Symbol strings

WorkspaceIconView.swiftSwift

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 .presentationDetents for 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).

Usage.swiftswift
// 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.

Products
Josh
Speaking
Experiments