uikit shenanigans: collectionview for the symbol picker??

This commit is contained in:
neon443
2025-06-14 17:45:38 +01:00
parent 4c9e72fad2
commit 2dd2c51059
8 changed files with 194 additions and 41 deletions

View File

@@ -12,6 +12,7 @@ struct ContentView: View {
@StateObject var settingsModel: SettingsViewModel @StateObject var settingsModel: SettingsViewModel
@State private var showAddEventView: Bool = false @State private var showAddEventView: Bool = false
@State private var symbolSearchInput: String = ""
var body: some View { var body: some View {
NavigationSplitView { NavigationSplitView {
@@ -34,6 +35,14 @@ struct ContentView: View {
Image(systemName: "tray.full") Image(systemName: "tray.full")
Text("Archive") Text("Archive")
} }
NavigationLink {
SymbolsPicker(
selection: $symbolSearchInput
)
} label: {
Image(systemName: "star.circle")
Text("Symbols")
}
NavigationLink { NavigationLink {
SettingsView( SettingsView(
viewModel: viewModel, viewModel: viewModel,
@@ -43,14 +52,6 @@ struct ContentView: View {
Image(systemName: "gear") Image(systemName: "gear")
Text("Settings") Text("Settings")
} }
NavigationLink {
SymbolsPicker(
selection: .constant("")
)
} label: {
Image(systemName: "gear")
Text("Settings")
}
} }
} detail: { } detail: {
Text("Welcome to Near Future") Text("Welcome to Near Future")

View File

@@ -74,6 +74,12 @@
A98C20CE2DE7308E0008D61C /* ArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CD2DE7308E0008D61C /* ArchiveView.swift */; }; A98C20CE2DE7308E0008D61C /* ArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CD2DE7308E0008D61C /* ArchiveView.swift */; };
A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CF2DE731BD0008D61C /* HomeView.swift */; }; A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CF2DE731BD0008D61C /* HomeView.swift */; };
A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20D32DE7339E0008D61C /* AboutView.swift */; }; A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20D32DE7339E0008D61C /* AboutView.swift */; };
A9C769A12DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A9C769A02DFDD1FC00082FFF /* SymbolsPicker.storyboard */; };
A9C769A22DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A9C769A02DFDD1FC00082FFF /* SymbolsPicker.storyboard */; };
A9C769A32DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A9C769A02DFDD1FC00082FFF /* SymbolsPicker.storyboard */; };
A9C769A52DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */; };
A9C769A62DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */; };
A9C769A72DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */; };
A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */; }; A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@@ -158,6 +164,8 @@
A98C20CD2DE7308E0008D61C /* ArchiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchiveView.swift; sourceTree = "<group>"; }; A98C20CD2DE7308E0008D61C /* ArchiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchiveView.swift; sourceTree = "<group>"; };
A98C20CF2DE731BD0008D61C /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; }; A98C20CF2DE731BD0008D61C /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
A98C20D32DE7339E0008D61C /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; }; A98C20D32DE7339E0008D61C /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
A9C769A02DFDD1FC00082FFF /* SymbolsPicker.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SymbolsPicker.storyboard; sourceTree = "<group>"; };
A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolsPickerStoryboard.swift; sourceTree = "<group>"; };
A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgets.swift; sourceTree = "<group>"; }; A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgets.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@@ -245,6 +253,8 @@
children = ( children = (
A91EF8172DFD77BF00B8463D /* SymbolsLoader.swift */, A91EF8172DFD77BF00B8463D /* SymbolsLoader.swift */,
A91EF81B2DFD796600B8463D /* SymbolsPicker.swift */, A91EF81B2DFD796600B8463D /* SymbolsPicker.swift */,
A9C769A02DFDD1FC00082FFF /* SymbolsPicker.storyboard */,
A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */,
); );
path = SymbolsPicker; path = SymbolsPicker;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -497,6 +507,7 @@
files = ( files = (
A90D49452DDE1C7600781124 /* Tints.xcassets in Resources */, A90D49452DDE1C7600781124 /* Tints.xcassets in Resources */,
A90D493E2DDE10CF00781124 /* Assets.xcassets in Resources */, A90D493E2DDE10CF00781124 /* Assets.xcassets in Resources */,
A9C769A12DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */,
A90D493D2DDE10B200781124 /* NearFutureIcon.png in Resources */, A90D493D2DDE10B200781124 /* NearFutureIcon.png in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -507,6 +518,7 @@
files = ( files = (
A90D49442DDE1C7600781124 /* Tints.xcassets in Resources */, A90D49442DDE1C7600781124 /* Tints.xcassets in Resources */,
A920C2922D24011A00E4F9B1 /* Preview Assets.xcassets in Resources */, A920C2922D24011A00E4F9B1 /* Preview Assets.xcassets in Resources */,
A9C769A22DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */,
A949F8322DCAAA8A0064DCA0 /* NearFutureIcon.png in Resources */, A949F8322DCAAA8A0064DCA0 /* NearFutureIcon.png in Resources */,
A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */, A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */,
); );
@@ -517,6 +529,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A90D49462DDE1C7A00781124 /* Tints.xcassets in Resources */, A90D49462DDE1C7A00781124 /* Tints.xcassets in Resources */,
A9C769A32DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */,
A979F6102D270AF90094C0B3 /* Assets.xcassets in Resources */, A979F6102D270AF90094C0B3 /* Assets.xcassets in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -528,6 +541,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A9C769A52DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */,
A91EF80E2DFC9A0C00B8463D /* WhatsNewView.swift in Sources */, A91EF80E2DFC9A0C00B8463D /* WhatsNewView.swift in Sources */,
A91EF8192DFD77BF00B8463D /* SymbolsLoader.swift in Sources */, A91EF8192DFD77BF00B8463D /* SymbolsLoader.swift in Sources */,
A95E9EE42DFC77D400ED655F /* ImportView.swift in Sources */, A95E9EE42DFC77D400ED655F /* ImportView.swift in Sources */,
@@ -576,6 +590,7 @@
A949F8512DCAABE00064DCA0 /* ExportView.swift in Sources */, A949F8512DCAABE00064DCA0 /* ExportView.swift in Sources */,
A95E9ED82DFC742B00ED655F /* AccentIcon.swift in Sources */, A95E9ED82DFC742B00ED655F /* AccentIcon.swift in Sources */,
A90D49532DDE2D0000781124 /* Extensions.swift in Sources */, A90D49532DDE2D0000781124 /* Extensions.swift in Sources */,
A9C769A62DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */,
A949F8522DCAABE00064DCA0 /* iCloudSettingsView.swift in Sources */, A949F8522DCAABE00064DCA0 /* iCloudSettingsView.swift in Sources */,
A949F8532DCAABE00064DCA0 /* ImportView.swift in Sources */, A949F8532DCAABE00064DCA0 /* ImportView.swift in Sources */,
A949F8542DCAABE00064DCA0 /* SettingsView.swift in Sources */, A949F8542DCAABE00064DCA0 /* SettingsView.swift in Sources */,
@@ -596,6 +611,7 @@
A95E9EDA2DFC742B00ED655F /* AccentIcon.swift in Sources */, A95E9EDA2DFC742B00ED655F /* AccentIcon.swift in Sources */,
A91EF80D2DFC910000B8463D /* ViewModifiers.swift in Sources */, A91EF80D2DFC910000B8463D /* ViewModifiers.swift in Sources */,
A91EF8182DFD77BF00B8463D /* SymbolsLoader.swift in Sources */, A91EF8182DFD77BF00B8463D /* SymbolsLoader.swift in Sources */,
A9C769A72DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */,
A91EF8072DFC8B8B00B8463D /* ColorCodable.swift in Sources */, A91EF8072DFC8B8B00B8463D /* ColorCodable.swift in Sources */,
A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */, A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */,
A979F60C2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift in Sources */, A979F60C2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift in Sources */,

View File

@@ -33,7 +33,8 @@ struct ContentView: View {
Label("Archive", systemImage: "tray.full") Label("Archive", systemImage: "tray.full")
} }
.tag(Tab.archive) .tag(Tab.archive)
StatsView(viewModel: viewModel) // StatsView(viewModel: viewModel)
SymbolsPickerStoryboardUIViewRepresentable()
.tabItem { .tabItem {
Label("Statistics", systemImage: "chart.pie") Label("Statistics", systemImage: "chart.pie")
} }

View File

@@ -6,7 +6,6 @@
// //
import SwiftUI import SwiftUI
import SFSymbolsPicker
struct AddEventView: View { struct AddEventView: View {
@ObservedObject var viewModel: EventViewModel @ObservedObject var viewModel: EventViewModel

View File

@@ -11,7 +11,6 @@ import SwiftUI
enum HelpType { enum HelpType {
case Search case Search
case Archive case Archive
case SymbolsSearch
} }
enum Field { enum Field {
@@ -36,16 +35,6 @@ struct HelpView: View {
self.focusedField = nil self.focusedField = nil
} }
/// initialises a symbolspciker helpview
/// - Parameters:
/// - searchInput: biding string
/// - searchFocused: a field
init(symbolsSearchInput: Binding<String>, focusedField: Field?) {
_searchInput = symbolsSearchInput
self.helpType = .SymbolsSearch
_showAddEvent = .constant(false)
}
@Binding var searchInput: String @Binding var searchInput: String
@FocusState var focusedField: Field? @FocusState var focusedField: Field?
@@ -84,17 +73,6 @@ struct HelpView: View {
buttonSymbol: "plus", buttonSymbol: "plus",
buttonText: "Create an event" buttonText: "Create an event"
) )
case .SymbolsSearch:
return (
symbol: "magnifyingglass",
title: "You look lost",
body: "The symbol picker search only works with exact matches, try a different search term.",
buttonAction: {
searchInput = ""
},
buttonSymbol: "xmark",
buttonText: "Clear Search bar"
)
} }
} }
var body: some View { var body: some View {

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24053.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="collection view cell content view" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Symbols Picker Storyboard-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController storyboardIdentifier="SymbolsPicker" id="Y6W-OH-hqX" customClass="SymbolsPickerStoryboard" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="xBf-3w-4Ao">
<rect key="frame" x="0.0" y="118" width="393" height="666"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<collectionViewFlowLayout key="collectionViewLayout" automaticEstimatedItemSize="YES" minimumLineSpacing="10" minimumInteritemSpacing="10" id="d2N-B5-D5N">
<size key="itemSize" width="100" height="100"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="nKx-2O-Nq5" customClass="SymbolCell" customModule="NearFuture" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="100" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<collectionViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="3DG-aV-ZH4">
<rect key="frame" x="0.0" y="0.0" width="100" height="100"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AaY-Po-OoS">
<rect key="frame" x="0.0" y="0.0" width="100" height="84"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gGM-kQ-cA7">
<rect key="frame" x="29" y="79" width="42" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</collectionViewCellContentView>
<connections>
<outlet property="imageView" destination="AaY-Po-OoS" id="Swa-vO-Mtz"/>
<outlet property="textLabel" destination="gGM-kQ-cA7" id="Qei-Qd-rn5"/>
</connections>
</collectionViewCell>
</cells>
</collectionView>
</subviews>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<connections>
<outlet property="collectionView" destination="xBf-3w-4Ao" id="c9h-Ew-aOX"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="139.69465648854961" y="65.492957746478879"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@@ -13,15 +13,15 @@ struct SymbolsPicker: View {
@FocusState var searchfocuesd: Bool @FocusState var searchfocuesd: Bool
@State var searchInput: String = "skldlkdsklsddkls" @State var searchInput: String = ""
var symbols: [String] { var symbols: [String] {
return symbolsLoader.getSymbols(searchInput) return symbolsLoader.getSymbols(searchInput)
} }
private func gridLayout(forWidth geoSizeWidth: CGFloat) -> [GridItem] { private func gridLayout(forWidth geoSizeWidth: CGFloat) -> [GridItem] {
let gridItem = GridItem(.fixed(40), spacing: 20, alignment: .center) let gridItem = GridItem(.fixed(80), spacing: 20, alignment: .center)
let columns = Int(geoSizeWidth/60.rounded(.up)) let columns = Int(geoSizeWidth/100.rounded(.up))
return Array(repeating: gridItem, count: columns) return Array(repeating: gridItem, count: columns)
} }
@@ -45,13 +45,18 @@ struct SymbolsPicker: View {
Button() { Button() {
selection = symbol selection = symbol
} label: { } label: {
VStack {
Image(systemName: symbol) Image(systemName: symbol)
.resizable() .resizable()
.scaledToFit() .scaledToFit()
.frame(maxWidth: 40, maxHeight: 40)
.symbolRenderingMode(.palette) .symbolRenderingMode(.palette)
.foregroundStyle(.blue, .gray, .black) .foregroundStyle(.blue, .gray, .black)
Text(symbol)
.truncationMode(.middle)
.font(.footnote)
} }
}
.frame(maxWidth: 80, maxHeight: 80)
.buttonStyle(.plain) .buttonStyle(.plain)
} }
} }

View File

@@ -0,0 +1,77 @@
//
// SymbolsPickerStoryboard.swift
// NearFuture
//
// Created by neon443 on 14/06/2025.
//
import Foundation
import SwiftUI
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var symbolLoader: SymbolsLoader = SymbolsLoader()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.itemSize = CGSize(
width: 100,
height: 100
)
}
}
}
extension ViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
symbolLoader.allSymbols.count
}
func collectionView(
_ collectionView: UICollectionView,
numberOfItemsInSection section: Int
) -> Int {
10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! SymbolCell
let imageView = cell.imageView
imageView?.image = UIImage(systemName: symbolLoader.allSymbols[indexPath.item])
cell.textLabel?.text = "hi\(indexPath.row)"
return cell
}
}
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(indexPath.item + 1)
}
}
class SymbolCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var textLabel: UILabel!
}
struct SymbolsPickerStoryboardUIViewRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> some UIView {
let storyboard = UIStoryboard(name: "SymbolsPicker", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "SymbolsPicker") as! ViewController
return viewController.view
}
func updateUIView(_ uiView: UIViewType, context: Context) {
print()
}
}