persist pickerView tab selection

This commit is contained in:
True Zhuanjia committed 2026-04-10 23:25:46 +08:00
1 parent 8fd43d47dd
commit ca69fd62d9
3 files changed
+67 -10

No files matched your search

@@ -274,7 +274,7 @@ static CGRect layoutViewBounds;
} }
- (OSCProfile *) getSelectedProfile { - (OSCProfile *) getSelectedProfile {
NSLog(@"getAllProfiles test %f", CACurrentMediaTime()); // NSLog(@"getAllProfiles test %f", CACurrentMediaTime());
NSMutableArray *profiles = [self getAllProfiles]; NSMutableArray *profiles = [self getAllProfiles];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+59 -9
View File
@@ -9,6 +9,11 @@
import SwiftUI import SwiftUI
import UIKit import UIKit
@available(iOS 13.0, *)
final class WidgetPickerPresentationState: ObservableObject {
@Published var hasHostAppeared = false
}
@available(iOS 13.0, *) @available(iOS 13.0, *)
enum WidgetPickerTab: String, CaseIterable, Identifiable, Equatable { enum WidgetPickerTab: String, CaseIterable, Identifiable, Equatable {
case gamepad = "Gamepad" case gamepad = "Gamepad"
@@ -17,6 +22,17 @@ enum WidgetPickerTab: String, CaseIterable, Identifiable, Equatable {
var id: String { rawValue } var id: String { rawValue }
var persistenceIdentifier: String {
switch self {
case .gamepad:
return "gamepad"
case .keyboard:
return "keyboard"
case .functional:
return "functional"
}
}
var title: String { var title: String {
switch self { switch self {
case .gamepad: case .gamepad:
@@ -271,6 +287,8 @@ private struct WidgetPickerMetrics {
@available(iOS 13.0, *) @available(iOS 13.0, *)
struct WidgetPickerView: View { struct WidgetPickerView: View {
private static let lastSelectedTabDefaultsKey = "WidgetPickerView.lastSelectedTabIdentifier"
private enum PoolTipMessageType { private enum PoolTipMessageType {
case normal case normal
case error case error
@@ -286,6 +304,7 @@ struct WidgetPickerView: View {
private let keyboardPickerMode: VirtualKeyboardMode private let keyboardPickerMode: VirtualKeyboardMode
private let shortcutPickerTipText: String? private let shortcutPickerTipText: String?
private let shortcutIdentifier: String? private let shortcutIdentifier: String?
@ObservedObject private var presentationState: WidgetPickerPresentationState
var onWidgetCreated: (([String: String]) -> Void)? = nil var onWidgetCreated: (([String: String]) -> Void)? = nil
var onCloseRequested: (() -> Void)? = nil var onCloseRequested: (() -> Void)? = nil
@@ -312,6 +331,15 @@ struct WidgetPickerView: View {
@SwiftUI.State private var didApplyInitialConfiguration: Bool = false @SwiftUI.State private var didApplyInitialConfiguration: Bool = false
@SwiftUI.State private var selectionSyncToken: Int = 0 @SwiftUI.State private var selectionSyncToken: Int = 0
private static func restoredTab(from availableTabs: [WidgetPickerTab]) -> WidgetPickerTab {
if let persistedIdentifier = UserDefaults.standard.string(forKey: lastSelectedTabDefaultsKey),
let persistedTab = WidgetPickerTab(identifier: persistedIdentifier),
availableTabs.contains(persistedTab) {
return persistedTab
}
return availableTabs[0]
}
init( init(
isEditMode: Bool = false, isEditMode: Bool = false,
initialCmdString: String? = nil, initialCmdString: String? = nil,
@@ -322,6 +350,7 @@ struct WidgetPickerView: View {
keyboardPickerMode: VirtualKeyboardMode = .picker, keyboardPickerMode: VirtualKeyboardMode = .picker,
shortcutPickerTipText: String? = nil, shortcutPickerTipText: String? = nil,
shortcutIdentififier: String? = nil, shortcutIdentififier: String? = nil,
presentationState: WidgetPickerPresentationState = WidgetPickerPresentationState(),
onWidgetCreated: (([String: String]) -> Void)? = nil, onWidgetCreated: (([String: String]) -> Void)? = nil,
onCloseRequested: (() -> Void)? = nil onCloseRequested: (() -> Void)? = nil
) { ) {
@@ -336,9 +365,14 @@ struct WidgetPickerView: View {
self.keyboardPickerMode = keyboardPickerMode self.keyboardPickerMode = keyboardPickerMode
self.shortcutPickerTipText = shortcutPickerTipText self.shortcutPickerTipText = shortcutPickerTipText
self.shortcutIdentifier = shortcutIdentififier self.shortcutIdentifier = shortcutIdentififier
self.presentationState = presentationState
self.onWidgetCreated = onWidgetCreated self.onWidgetCreated = onWidgetCreated
self.onCloseRequested = onCloseRequested self.onCloseRequested = onCloseRequested
_selectedTab = SwiftUI.State(initialValue: resolvedInitialTab ?? (normalizedTabs.contains(.keyboard) ? .keyboard : normalizedTabs[0])) _selectedTab = SwiftUI.State(
initialValue: isEditMode
? (resolvedInitialTab ?? (normalizedTabs.contains(.keyboard) ? .keyboard : normalizedTabs[0]))
: Self.restoredTab(from: normalizedTabs)
)
_tipMessage = SwiftUI.State( _tipMessage = SwiftUI.State(
initialValue: (keyboardPickerMode == .shortcutPicker && !(shortcutPickerTipText ?? "").isEmpty) initialValue: (keyboardPickerMode == .shortcutPicker && !(shortcutPickerTipText ?? "").isEmpty)
? (shortcutPickerTipText ?? "") ? (shortcutPickerTipText ?? "")
@@ -742,12 +776,18 @@ struct WidgetPickerView: View {
) )
.padding(pickerInsetKeyboard) .padding(pickerInsetKeyboard)
case .functional: case .functional:
FunctionalButtonCollectionView( Group {
items: functionalButtonOptions, if presentationState.hasHostAppeared {
isSelected: { selectedCmds.contains($0) }, FunctionalButtonCollectionView(
onSelect: { handleFunctionalButtonSelection($0) }, items: functionalButtonOptions,
onDeselect: { handleFunctionalButtonDeselection($0) } isSelected: { selectedCmds.contains($0) },
) onSelect: { handleFunctionalButtonSelection($0) },
onDeselect: { handleFunctionalButtonDeselection($0) }
)
} else {
Color.clear
}
}
.padding(pickerInsetFunctional) .padding(pickerInsetFunctional)
} }
} }
@@ -792,7 +832,7 @@ struct WidgetPickerView: View {
} }
Button(action: { Button(action: {
onCloseRequested?() handleCloseRequested()
}) { }) {
Image(systemName: "xmark") Image(systemName: "xmark")
.font(.system(size: max(modeButtonFontSize, 10), weight: .bold)) .font(.system(size: max(modeButtonFontSize, 10), weight: .bold))
@@ -1812,10 +1852,11 @@ struct WidgetPickerView: View {
private func submitWidgetPayload() { private func submitWidgetPayload() {
var payload = makeWidgetPayload() var payload = makeWidgetPayload()
persistCurrentTabSelection()
lastCreatedWidgetPayload = payload lastCreatedWidgetPayload = payload
setTipMessage(SwiftLocalizationHelper.localizedString(forKey: "Widget config generated")) setTipMessage(SwiftLocalizationHelper.localizedString(forKey: "Widget config generated"))
onWidgetCreated?(payload) onWidgetCreated?(payload)
print("widgetPicker payload =", payload as NSDictionary) // print("widgetPicker payload =", payload as NSDictionary)
setCreateWidgetSheetVisible(false) setCreateWidgetSheetVisible(false)
} }
@@ -1855,6 +1896,15 @@ struct WidgetPickerView: View {
} }
} }
private func persistCurrentTabSelection() {
UserDefaults.standard.set(selectedTab.persistenceIdentifier, forKey: Self.lastSelectedTabDefaultsKey)
}
private func handleCloseRequested() {
persistCurrentTabSelection()
onCloseRequested?()
}
private func applyInitialConfigurationIfNeeded() { private func applyInitialConfigurationIfNeeded() {
guard !didApplyInitialConfiguration else { return } guard !didApplyInitialConfiguration else { return }
didApplyInitialConfiguration = true didApplyInitialConfiguration = true
@@ -29,6 +29,7 @@ public final class WidgetPickerViewController: UIViewController {
public var shortcutPickerTipText: String? public var shortcutPickerTipText: String?
@objc public var shortcutIdentifier: String? @objc public var shortcutIdentifier: String?
private let presentationState = WidgetPickerPresentationState()
private var hostingViewController: UIHostingController<WidgetPickerView>? private var hostingViewController: UIHostingController<WidgetPickerView>?
public override func viewDidLoad() { public override func viewDidLoad() {
@@ -46,6 +47,7 @@ public final class WidgetPickerViewController: UIViewController {
keyboardPickerMode: keyboardPickerMode, keyboardPickerMode: keyboardPickerMode,
shortcutPickerTipText: shortcutPickerTipText, shortcutPickerTipText: shortcutPickerTipText,
shortcutIdentififier: shortcutIdentifier, shortcutIdentififier: shortcutIdentifier,
presentationState: presentationState,
onWidgetCreated: { [weak self] payload in onWidgetCreated: { [weak self] payload in
guard let self else { return } guard let self else { return }
self.delegate?.widgetPickerViewController(self, didCreateWidget: payload as NSDictionary) self.delegate?.widgetPickerViewController(self, didCreateWidget: payload as NSDictionary)
@@ -78,6 +80,11 @@ public final class WidgetPickerViewController: UIViewController {
navigationController?.setNavigationBarHidden(true, animated: false) navigationController?.setNavigationBarHidden(true, animated: false)
} }
public override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
presentationState.hasHostAppeared = true
}
private func resolvedTabs() -> [WidgetPickerTab] { private func resolvedTabs() -> [WidgetPickerTab] {
let tabs = tabIdentifiers.compactMap(WidgetPickerTab.init(identifier:)) let tabs = tabIdentifiers.compactMap(WidgetPickerTab.init(identifier:))
return tabs.isEmpty ? WidgetPickerTab.allCases : tabs return tabs.isEmpty ? WidgetPickerTab.allCases : tabs