95 lines
3.5 KiB
Swift
95 lines
3.5 KiB
Swift
//
|
|
// SymbolPickerView.swift
|
|
// Haru_Danim
|
|
//
|
|
// SF Symbols 아이콘 선택기 (검색 + 카테고리 탐색)
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct SymbolPickerView: View {
|
|
@Environment(\.dismiss) private var dismiss
|
|
@Binding var selection: String
|
|
|
|
@State private var searchText = ""
|
|
@State private var category: String
|
|
|
|
init(selection: Binding<String>) {
|
|
_selection = selection
|
|
_category = State(initialValue: SymbolCatalog.categories.first?.name ?? "")
|
|
}
|
|
|
|
private var symbols: [String] {
|
|
let trimmed = searchText.trimmingCharacters(in: .whitespaces).lowercased()
|
|
if !trimmed.isEmpty {
|
|
return SymbolCatalog.allSymbols.filter { $0.contains(trimmed) }
|
|
}
|
|
return SymbolCatalog.categories.first { $0.name == category }?.symbols ?? []
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
VStack(spacing: 0) {
|
|
if searchText.isEmpty {
|
|
categoryBar
|
|
}
|
|
ScrollView {
|
|
LazyVGrid(columns: [GridItem(.adaptive(minimum: 52), spacing: 10)], spacing: 10) {
|
|
ForEach(symbols, id: \.self) { symbol in
|
|
Button {
|
|
selection = symbol
|
|
dismiss()
|
|
} label: {
|
|
Image(systemName: symbol)
|
|
.font(.system(size: 22))
|
|
.foregroundStyle(symbol == selection ? Color.white : AppTheme.green)
|
|
.frame(width: 52, height: 52)
|
|
.background(
|
|
symbol == selection ? AppTheme.green : AppTheme.surface,
|
|
in: RoundedRectangle(cornerRadius: 12, style: .continuous)
|
|
)
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
}
|
|
.padding()
|
|
}
|
|
}
|
|
.background(AppTheme.background)
|
|
.navigationTitle("아이콘 선택")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.searchable(text: $searchText, prompt: "심볼 이름 검색 (영문)")
|
|
.toolbar {
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("닫기") { dismiss() }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private var categoryBar: some View {
|
|
ScrollView(.horizontal, showsIndicators: false) {
|
|
HStack(spacing: 8) {
|
|
ForEach(SymbolCatalog.categories) { cat in
|
|
Button {
|
|
category = cat.name
|
|
} label: {
|
|
Text(cat.name)
|
|
.font(.subheadline.weight(category == cat.name ? .semibold : .regular))
|
|
.padding(.horizontal, 14)
|
|
.padding(.vertical, 7)
|
|
.background(
|
|
category == cat.name ? AppTheme.green : AppTheme.surface,
|
|
in: Capsule()
|
|
)
|
|
.foregroundStyle(category == cat.name ? Color.white : Color.primary)
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
}
|
|
.padding(.horizontal)
|
|
.padding(.vertical, 8)
|
|
}
|
|
}
|
|
}
|