Recipes
SwiftUI View Modifier
SwiftUI View Modifier
A custom modifier to easily apply string keys to Text views.
Copy
struct StringbootKey: ViewModifier {
let key: String
let params: [String: Any]
@State private var text: String = ""
func body(content: Content) -> some View {
Text(text.isEmpty ? key : text)
.onAppear { loadString() }
.onReceive(Stringboot.shared.stringPublisher(for: key)) { newText in
self.text = newText
}
}
private func loadString() {
self.text = Stringboot.shared.string(forKey: key, params: params)
}
}
extension View {
func stringboot(_ key: String, params: [String: Any] = [:]) -> some View {
modifier(StringbootKey(key: key, params: params))
}
}
Localized Alerts
Localized Alerts
Showing localized alerts from a ViewModel.
Copy
class ProfileViewModel: ObservableObject {
@Published var showError = false
@Published var errorMessage = ""
func saveProfile() {
let errorKey = "error_save_failed"
self.errorMessage = Stringboot.shared.string(forKey: errorKey)
self.showError = true
}
}
Dynamic Date Formatting
Dynamic Date Formatting
Formatting dates based on the active Stringboot locale.
Copy
func localizedDate(_ date: Date) -> String {
let formatter = DateFormatter()
formatter.locale = Stringboot.shared.currentLocale
formatter.dateStyle = .long
formatter.timeStyle = .short
return formatter.string(from: date)
}
Plug-and-Play Components
Language Picker Sheet
Language Picker Sheet
A ready-to-use sheet for language selection.
Copy
struct LanguagePickerView: View {
@Environment(\.dismiss) var dismiss
@State private var languages: [Language] = []
var body: some View {
NavigationView {
List(languages, id: \.code) { lang in
Button(action: {
Stringboot.shared.setLocale(lang.code)
dismiss()
}) {
HStack {
Text(lang.name)
.foregroundColor(.primary)
Spacer()
if lang.code == Stringboot.shared.currentLocale {
Image(systemName: "checkmark")
.foregroundColor(.blue)
}
}
}
}
.navigationTitle("Select Language")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Close") { dismiss() }
}
}
}
.onAppear {
self.languages = Stringboot.shared.availableLanguages
}
}
}
FAQ Bottom Sheet
FAQ Bottom Sheet
A searchable FAQ browser.
Copy
struct FAQSheet: View {
let tag: String
@State private var faqs: [FAQ] = []
@Environment(\.dismiss) var dismiss
var body: some View {
NavigationView {
List(faqs) { faq in
DisclosureGroup(
content: { Text(faq.answer).padding(.vertical) },
label: { Text(faq.question).font(.headline) }
)
}
.navigationTitle("Help & Support")
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button("Done") { dismiss() }
}
}
}
.onAppear {
Task {
self.faqs = await FAQProvider.shared.getFAQs(tag: tag)
}
}
}
}