add possibility to implement custom EmojiProvider
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
B089F70829702B8400F0C479 /* EmojiPicker in Frameworks */ = {isa = PBXBuildFile; productRef = B089F70729702B8400F0C479 /* EmojiPicker */; };
|
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 */; };
|
B0DD3892296ED65900DEFE36 /* EmojiPickerSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0DD3891296ED65900DEFE36 /* EmojiPickerSampleApp.swift */; };
|
||||||
B0DD3894296ED65900DEFE36 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0DD3893296ED65900DEFE36 /* ContentView.swift */; };
|
B0DD3894296ED65900DEFE36 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0DD3893296ED65900DEFE36 /* ContentView.swift */; };
|
||||||
B0DD3896296ED65B00DEFE36 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B0DD3895296ED65B00DEFE36 /* Assets.xcassets */; };
|
B0DD3896296ED65B00DEFE36 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B0DD3895296ED65B00DEFE36 /* Assets.xcassets */; };
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
B089F70629702B7E00F0C479 /* EmojiPicker */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = EmojiPicker; path = ..; sourceTree = "<group>"; };
|
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; };
|
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>"; };
|
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>"; };
|
B0DD3893296ED65900DEFE36 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||||
@@ -61,6 +63,7 @@
|
|||||||
B0DD3893296ED65900DEFE36 /* ContentView.swift */,
|
B0DD3893296ED65900DEFE36 /* ContentView.swift */,
|
||||||
B0DD3895296ED65B00DEFE36 /* Assets.xcassets */,
|
B0DD3895296ED65B00DEFE36 /* Assets.xcassets */,
|
||||||
B0DD3897296ED65B00DEFE36 /* Preview Content */,
|
B0DD3897296ED65B00DEFE36 /* Preview Content */,
|
||||||
|
B0B09EC5297206F9005F41E9 /* LimitedEmojiProvider.swift */,
|
||||||
);
|
);
|
||||||
path = EmojiPickerSample;
|
path = EmojiPickerSample;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -160,6 +163,7 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
B0B09EC6297206F9005F41E9 /* LimitedEmojiProvider.swift in Sources */,
|
||||||
B0DD3894296ED65900DEFE36 /* ContentView.swift in Sources */,
|
B0DD3894296ED65900DEFE36 /* ContentView.swift in Sources */,
|
||||||
B0DD3892296ED65900DEFE36 /* EmojiPickerSampleApp.swift in Sources */,
|
B0DD3892296ED65900DEFE36 /* EmojiPickerSampleApp.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ struct ContentView: View {
|
|||||||
@State
|
@State
|
||||||
var displayEmojiPicker: Bool = false
|
var displayEmojiPicker: Bool = false
|
||||||
|
|
||||||
|
@State
|
||||||
|
var displayLimitedEmojiPicker: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
VStack {
|
VStack {
|
||||||
@@ -28,13 +31,30 @@ struct ContentView: View {
|
|||||||
Button {
|
Button {
|
||||||
displayEmojiPicker = true
|
displayEmojiPicker = true
|
||||||
} label: {
|
} 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()
|
.padding()
|
||||||
.sheet(isPresented: $displayEmojiPicker) {
|
.sheet(isPresented: $displayEmojiPicker) {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
EmojiPickerView(selectedEmoji: $selectedEmoji, selectedColor: .orange)
|
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")
|
.navigationTitle("Emojis")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.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)
|
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
|
## Samples
|
||||||
|
|
||||||
You can access to sample project on folder `EmojiPickerSample`
|
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 selectedColor: Color
|
||||||
private var searchEnabled: Bool
|
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._selectedEmoji = selectedEmoji
|
||||||
self.selectedColor = selectedColor
|
self.selectedColor = selectedColor
|
||||||
self.searchEnabled = searchEnabled
|
self.searchEnabled = searchEnabled
|
||||||
|
self.emojis = emojiProvider.getAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
let columns = [
|
let columns = [
|
||||||
GridItem(.adaptive(minimum: 80))
|
GridItem(.adaptive(minimum: 80))
|
||||||
]
|
]
|
||||||
|
|
||||||
let emojis = EmojiProvider().getAll()
|
let emojis: [Emoji]
|
||||||
|
|
||||||
private var searchResults: [Emoji] {
|
private var searchResults: [Emoji] {
|
||||||
if search.isEmpty {
|
if search.isEmpty {
|
||||||
|
|||||||
@@ -2,16 +2,11 @@
|
|||||||
// EmojiProvider.swift
|
// EmojiProvider.swift
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Created by Kévin Sibué on 11/01/2023.
|
// Created by Kévin Sibué on 13/01/2023.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
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