persist pickerView tab selection
This commit is contained in:
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];
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in new issue
Block a user