в приложении книжного клуба, которое я пытаюсь написать, у меня есть NavigationSplitView
, который отображает список читателей в выбираемом List
, который дает пользователю доступ к комментариям каждого читателя к данной книге. Вверху списка находится кнопка «Забронировать», которая возвращает пользователя на главную страницу книги:
struct ProjectView: View
{
@State private var readers: [Reader]
@State private var selectedReader: Reader?
init(readers: [Reader])
{
self.readers = readers
}
var body: some View
{
NavigationSplitView
{
List(selection: self.$selectedReader)
{
Button("Book")
{
self.selectedReader = nil
}
Divider()
ForEach (self.readers, id: \.self)
{
reader in Text(reader.name)
}
}
}
detail:
{
if let selectedReader = self.selectedReader
{
ReaderView(reader: selectedReader)
}
else
{
BookView()
}
}
#if os(macOS)
.navigationSplitViewColumnWidth(min: 180, ideal: 200)
#endif
.navigationTitle(self.project.name)
}
}
Я пытаюсь сделать так, чтобы "Книга" выделялась/подсвечивалась так же, как и имена читателей в списке читателей, вы можете увидеть, что я имею в виду в этом видео:
https://youtube.com/shorts/__IA890FxG0?feature=share
Кто-нибудь знает, как это сделать? Или это вообще возможно?
@workingdogsupportUkraine Спасибо за советы. Забыл добавить объявление для selectedReader, поменял.
Следует использовать ReaderOrBook?
, так как выбором может быть либо читалка, либо «Книга», либо вообще ничего не выбрано (nil
).
enum ReaderOrBook: Hashable {
case book
case reader(Reader)
// convenient property to convert a ReaderOrBook to a Reader
var asReader: Reader? {
if case let .reader(r) = self {
return r
}
return nil
}
}
Тогда вам просто нужно tag
правильно расположить строки списка.
struct ProjectView: View {
// this should not be a @State since you want callers to pass in an array of readers
// if you want to mutate this in ProjectView, make it a @Binding instead
let readers: [Reader]
@State private var selectedReaderOrBook: ReaderOrBook?
var body: some View {
NavigationSplitView {
List(selection: self.$selectedReaderOrBook) {
Text("Book").tag(ReaderOrBook.book)
Divider()
ForEach (self.readers, id: \.self) { reader in
Text(reader.name)
.tag(ReaderOrBook.reader(reader))
}
}
} detail: {
// ...
}
}
}
Ух ты, это такое замечательное решение, я только что реализовал его, и оно работало отлично. Большое спасибо!
Обратите внимание: вы не должны инициализировать
self.readers = readers
, это должно быть_readers = State(initialValue: readers)
или использоватьlet readers: [Reader]
. Если вам нужно сменить читателя, используйте@Binding
. Также не стоит использоватьForEach (self.readers, id: \.self)
, сделайте структуру ReaderIdentifiable
. Как вы заявляетеselectedReader
? Обратите внимание:Above the list of readers is a home button "Book" ...
нет, кнопка находится вверху списка, а не над ним.