#swift #macos #swiftui
Вопрос:
В приложении для Mac я пытаюсь сохранить выбор списка SwiftUI с помощью AppStorage. Цель состоит в том, чтобы приложение запомнило последний выбор таким образом, чтобы он был выбран при перезапуске приложения. Я не могу понять, как привязать выделение к свойству AppStorage. Есть какие-нибудь предложения о том, как этого добиться?
enum Fruit: String, CaseIterable, Identifiable {
case apple
case orange
case mango
case lemon
var id: String { rawValue }
}
struct Sidebar: View {
@Binding var selection: Fruit
var body: some View {
List(Fruit.allCases, id: .self, selection: $selection) { fruit in
Text(fruit.rawValue)
}
.listStyle(SidebarListStyle())
.frame(minWidth: 150)
}
}
struct DetailView: View {
var selection: Fruit
var body: some View {
switch selection {
case .apple:
Text("🍎 (selection.rawValue)").font(.title).frame(minWidth: 200)
case .orange:
Text("🍊 (selection.rawValue)").font(.title).frame(minWidth: 200)
case .mango:
Text("🥭 (selection.rawValue)").font(.title).frame(minWidth: 200)
case .lemon:
Text("🍋 (selection.rawValue)").font(.title).frame(minWidth: 200)
}
}
}
struct ContentView: View {
@AppStorage("selection") private var selection: Fruit = .apple
var body: some View {
NavigationView {
Sidebar(selection: $selection)
DetailView(selection: selection)
}
.frame(width: 500, height: 300)
}
}
Комментарии:
1. Попробуйте выбрать onTapGesture = фрукты в виде боковой панели . Я почти уверен, что вы не можете использовать выбор списка, как вы используете выбор выбора.
2. Вы можете поместить необязательный выбор в a
List
. См. Список . Однако список не принимает прямую@AppStorage
в качестве прямой привязки. Ваш способ-это простое решение этой проблемы…
Ответ №1:
Используйте пользовательскую привязку при выборе.
struct Sidebar: View {
@Binding var selection: Fruit
var body: some View {
List(Fruit.allCases, id: .self, selection: Binding($selection)) { fruit in
Text(fruit.rawValue)
}
.listStyle(SidebarListStyle())
.frame(minWidth: 150)
}
}
или
List(Fruit.allCases, id: .self, selection: Binding(get: {selection}, set: {selection = $0 ?? Fruit.apple}$selection)) {
Комментарии:
1. Почему бы не использовать
Binding($selection)
?2. @шевеление, да. Это альтернатива. Но ты правильно понял идею?
3. Можете ли вы добавить к своему ответу
Binding($selection)
подход? Просто чтобы другие знали об этом.4. Я имел в виду, что в своем ответе вы показываете оба подхода. Таким образом, люди знают об обоих способах решения проблемы. Поэтому, пожалуйста, также покажите свой оригинальный ответ.
Ответ №2:
В вашем нет ничего плохого Binding
. Вам просто нужен способ выбора различных фруктов:
List(Fruit.allCases, id: .self) { fruit in
Text(fruit.rawValue)
.onTapGesture {
selection = fruit
}
}
В противном случае он отлично работает с тем, что вы закодировали.
Я не уверен, как у вас это не получается, но вот видео: Запись экрана 2021-10-04 в 11.10.29 утра(720)
Комментарии:
1. Это не работает. Он удаляет
$selection
привязку из списка, поэтому выбранный элемент не обновляется.2. Он был протестирован на Xcode 13RC и macOS 11.6.
3. Я также использовал Xcode 13 на macOS 11.6, но выбор списка не работает. Если нет
List(selection:)
, то как вы обновляете состояние списка? В вашем примереselection
обновляется привязка для представления, а не для списка.4. Обновлено видео, показывающее, что оно работает.
5. В вашем видео элементы боковой панели не выделяются при выборе элемента, поскольку состояние выбора в списке не обновляется. Вот изображение рабочего примера pasteboard.co/pJsuXvA8Sgop.png