From d787591e2121b617209172ad6a8ebf2975f605ae Mon Sep 17 00:00:00 2001 From: Kelvas Date: Fri, 13 Jan 2023 22:50:46 +0100 Subject: [PATCH] add possibility to implement custom EmojiProvider --- .../project.pbxproj | 4 ++ .../EmojiPickerSample/ContentView.swift | 22 +++++++++- .../LimitedEmojiProvider.swift | 23 ++++++++++ README.md | 42 +++++++++++++++++++ .../EmojiPicker/DefaultEmojiProvider.swift | 19 +++++++++ Sources/EmojiPicker/EmojiPickerView.swift | 5 ++- Sources/EmojiPicker/EmojiProvider.swift | 11 ++--- 7 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 EmojiPickerSample/EmojiPickerSample/LimitedEmojiProvider.swift create mode 100644 Sources/EmojiPicker/DefaultEmojiProvider.swift diff --git a/EmojiPickerSample/EmojiPickerSample.xcodeproj/project.pbxproj b/EmojiPickerSample/EmojiPickerSample.xcodeproj/project.pbxproj index 3a07f8b..b2c035c 100644 --- a/EmojiPickerSample/EmojiPickerSample.xcodeproj/project.pbxproj +++ b/EmojiPickerSample/EmojiPickerSample.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ B089F70829702B8400F0C479 /* EmojiPicker in Frameworks */ = {isa = PBXBuildFile; productRef = B089F70729702B8400F0C479 /* EmojiPicker */; }; + B0B09EC6297206F9005F41E9 /* LimitedEmojiProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0B09EC5297206F9005F41E9 /* LimitedEmojiProvider.swift */; }; B0DD3892296ED65900DEFE36 /* EmojiPickerSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0DD3891296ED65900DEFE36 /* EmojiPickerSampleApp.swift */; }; B0DD3894296ED65900DEFE36 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0DD3893296ED65900DEFE36 /* ContentView.swift */; }; B0DD3896296ED65B00DEFE36 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B0DD3895296ED65B00DEFE36 /* Assets.xcassets */; }; @@ -16,6 +17,7 @@ /* Begin PBXFileReference section */ B089F70629702B7E00F0C479 /* EmojiPicker */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = EmojiPicker; path = ..; sourceTree = ""; }; + B0B09EC5297206F9005F41E9 /* LimitedEmojiProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LimitedEmojiProvider.swift; sourceTree = ""; }; B0DD388E296ED65900DEFE36 /* EmojiPickerSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EmojiPickerSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; B0DD3891296ED65900DEFE36 /* EmojiPickerSampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerSampleApp.swift; sourceTree = ""; }; B0DD3893296ED65900DEFE36 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -61,6 +63,7 @@ B0DD3893296ED65900DEFE36 /* ContentView.swift */, B0DD3895296ED65B00DEFE36 /* Assets.xcassets */, B0DD3897296ED65B00DEFE36 /* Preview Content */, + B0B09EC5297206F9005F41E9 /* LimitedEmojiProvider.swift */, ); path = EmojiPickerSample; sourceTree = ""; @@ -160,6 +163,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B0B09EC6297206F9005F41E9 /* LimitedEmojiProvider.swift in Sources */, B0DD3894296ED65900DEFE36 /* ContentView.swift in Sources */, B0DD3892296ED65900DEFE36 /* EmojiPickerSampleApp.swift in Sources */, ); diff --git a/EmojiPickerSample/EmojiPickerSample/ContentView.swift b/EmojiPickerSample/EmojiPickerSample/ContentView.swift index b5a622d..7b18538 100644 --- a/EmojiPickerSample/EmojiPickerSample/ContentView.swift +++ b/EmojiPickerSample/EmojiPickerSample/ContentView.swift @@ -16,6 +16,9 @@ struct ContentView: View { @State var displayEmojiPicker: Bool = false + @State + var displayLimitedEmojiPicker: Bool = false + var body: some View { VStack { VStack { @@ -28,13 +31,30 @@ struct ContentView: View { Button { displayEmojiPicker = true } label: { - Text("Select emoji") + Text("Select standard emoji") } + .buttonStyle(.borderedProminent) + Button { + displayLimitedEmojiPicker = true + } label: { + Text("Select limited emoji (custom provider)") + } + .buttonStyle(.borderedProminent) + .padding(.top, 8) } .padding() .sheet(isPresented: $displayEmojiPicker) { NavigationView { EmojiPickerView(selectedEmoji: $selectedEmoji, selectedColor: .orange) + .padding(.top, 32) + .navigationTitle("Emojis") + .navigationBarTitleDisplayMode(.inline) + } + } + .sheet(isPresented: $displayLimitedEmojiPicker) { + NavigationView { + EmojiPickerView(selectedEmoji: $selectedEmoji, selectedColor: .orange, emojiProvider: LimitedEmojiProvider()) + .padding(.top, 32) .navigationTitle("Emojis") .navigationBarTitleDisplayMode(.inline) } diff --git a/EmojiPickerSample/EmojiPickerSample/LimitedEmojiProvider.swift b/EmojiPickerSample/EmojiPickerSample/LimitedEmojiProvider.swift new file mode 100644 index 0000000..14b648f --- /dev/null +++ b/EmojiPickerSample/EmojiPickerSample/LimitedEmojiProvider.swift @@ -0,0 +1,23 @@ +// +// LimitedEmojiProvider.swift +// EmojiPickerSample +// +// Created by Kévin Sibué on 13/01/2023. +// + +import Foundation +import EmojiPicker + +final class LimitedEmojiProvider: EmojiProvider { + + func getAll() -> [Emoji] { + return [ + Emoji(value: "🚀", name: "rocket"), + Emoji(value: "🇫🇷", name: "France"), + Emoji(value: "🦄", name: "unicorn"), + Emoji(value: "🍺", name: "beer"), + Emoji(value: "💶", name: "euro") + ] + } + +} diff --git a/README.md b/README.md index 112bd7a..1e09af2 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,48 @@ By default the search for emoji is allowed in the picker, it is however possible EmojiPickerView(selectedEmoji: $selectedEmoji, searchEnabled: false) ``` +⚠️ **WARNING** Search is only possible when `EmojiPicker` is embed on `NavigationView`. + +### Custom emoji provider + +`EmojiPickerView` embeds `EmojiProvider` protocol with a default implementation: `DefaultEmojiProvider`. This class allows to retrieve all existing emojis. + +When you build an `EmojiPickerView`, by default it uses this class to get the list of emojis to display. + +If you want to use your own emoji list, you can create your own class by implementing the `EmojiProvider` protocol : + +```swift +import Foundation +import EmojiPicker + +final class LimitedEmojiProvider: EmojiProvider { + + func getAll() -> [Emoji] { + return [ + Emoji(value: "🚀", name: "rocket"), + Emoji(value: "🇫🇷", name: "France"), + Emoji(value: "🦄", name: "unicorn"), + Emoji(value: "🍺", name: "beer"), + Emoji(value: "💶", name: "euro") + ] + } + +} +``` + +And then use it in the creation of the view: + +```swift +... +NavigationView { + EmojiPickerView(selectedEmoji: $selectedEmoji, selectedColor: .orange, emojiProvider: LimitedEmojiProvider()) + .padding(.top, 32) + .navigationTitle("Emojis") + .navigationBarTitleDisplayMode(.inline) +} +... +``` + ## Samples You can access to sample project on folder `EmojiPickerSample` diff --git a/Sources/EmojiPicker/DefaultEmojiProvider.swift b/Sources/EmojiPicker/DefaultEmojiProvider.swift new file mode 100644 index 0000000..8b985bb --- /dev/null +++ b/Sources/EmojiPicker/DefaultEmojiProvider.swift @@ -0,0 +1,19 @@ +// +// DefaultEmojiProvider.swift +// +// +// Created by Kévin Sibué on 11/01/2023. +// + +import Foundation +import Smile + +public final class DefaultEmojiProvider: EmojiProvider { + + public init() { } + + public func getAll() -> [Emoji] { + return Smile.list().map({ Emoji(value: $0, name: name(emoji: $0).first ?? "") }) + } + +} diff --git a/Sources/EmojiPicker/EmojiPickerView.swift b/Sources/EmojiPicker/EmojiPickerView.swift index 4fcba06..e2cebf3 100644 --- a/Sources/EmojiPicker/EmojiPickerView.swift +++ b/Sources/EmojiPicker/EmojiPickerView.swift @@ -21,17 +21,18 @@ public struct EmojiPickerView: View { private var selectedColor: Color private var searchEnabled: Bool - public init(selectedEmoji: Binding, searchEnabled: Bool = false, selectedColor: Color = .blue) { + public init(selectedEmoji: Binding, searchEnabled: Bool = false, selectedColor: Color = .blue, emojiProvider: EmojiProvider = DefaultEmojiProvider()) { self._selectedEmoji = selectedEmoji self.selectedColor = selectedColor self.searchEnabled = searchEnabled + self.emojis = emojiProvider.getAll() } let columns = [ GridItem(.adaptive(minimum: 80)) ] - let emojis = EmojiProvider().getAll() + let emojis: [Emoji] private var searchResults: [Emoji] { if search.isEmpty { diff --git a/Sources/EmojiPicker/EmojiProvider.swift b/Sources/EmojiPicker/EmojiProvider.swift index f8c5206..012a5dd 100644 --- a/Sources/EmojiPicker/EmojiProvider.swift +++ b/Sources/EmojiPicker/EmojiProvider.swift @@ -2,16 +2,11 @@ // EmojiProvider.swift // // -// Created by Kévin Sibué on 11/01/2023. +// Created by Kévin Sibué on 13/01/2023. // import Foundation -import Smile - -public final class EmojiProvider { - - func getAll() -> [Emoji] { - return Smile.list().map({ Emoji(value: $0, name: name(emoji: $0).first ?? "") }) - } +public protocol EmojiProvider { + func getAll() -> [Emoji] }