add possibility to implement custom EmojiProvider
This commit is contained in:
@@ -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 = "<group>"; };
|
||||
B0B09EC5297206F9005F41E9 /* LimitedEmojiProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LimitedEmojiProvider.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
B0DD3893296ED65900DEFE36 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
@@ -61,6 +63,7 @@
|
||||
B0DD3893296ED65900DEFE36 /* ContentView.swift */,
|
||||
B0DD3895296ED65B00DEFE36 /* Assets.xcassets */,
|
||||
B0DD3897296ED65B00DEFE36 /* Preview Content */,
|
||||
B0B09EC5297206F9005F41E9 /* LimitedEmojiProvider.swift */,
|
||||
);
|
||||
path = EmojiPickerSample;
|
||||
sourceTree = "<group>";
|
||||
@@ -160,6 +163,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B0B09EC6297206F9005F41E9 /* LimitedEmojiProvider.swift in Sources */,
|
||||
B0DD3894296ED65900DEFE36 /* ContentView.swift in Sources */,
|
||||
B0DD3892296ED65900DEFE36 /* EmojiPickerSampleApp.swift in Sources */,
|
||||
);
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
42
README.md
42
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`
|
||||
|
||||
19
Sources/EmojiPicker/DefaultEmojiProvider.swift
Normal file
19
Sources/EmojiPicker/DefaultEmojiProvider.swift
Normal file
@@ -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 ?? "") })
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,17 +21,18 @@ public struct EmojiPickerView: View {
|
||||
private var selectedColor: Color
|
||||
private var searchEnabled: Bool
|
||||
|
||||
public init(selectedEmoji: Binding<Emoji?>, searchEnabled: Bool = false, selectedColor: Color = .blue) {
|
||||
public init(selectedEmoji: Binding<Emoji?>, 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 {
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user