iOS: fix chapters list to open at current chapter without auto-scroll animation
Replace ScrollViewReader with scrollPosition to instantly show the current chapter without visible scrolling. This scales better for books with 1000+ chapters.
This commit is contained in:
@@ -721,70 +721,66 @@ struct ChaptersListSheet: View {
|
|||||||
let onChapterSelect: (Int) -> Void
|
let onChapterSelect: (Int) -> Void
|
||||||
|
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@State private var scrollPosition: Int?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
ScrollViewReader { proxy in
|
List {
|
||||||
List {
|
ForEach(chapters, id: \.number) { chapter in
|
||||||
ForEach(chapters, id: \.number) { chapter in
|
Button {
|
||||||
Button {
|
onChapterSelect(chapter.number)
|
||||||
onChapterSelect(chapter.number)
|
} label: {
|
||||||
} label: {
|
HStack(spacing: 12) {
|
||||||
HStack(spacing: 12) {
|
// Chapter number badge
|
||||||
// Chapter number badge
|
Text("\(chapter.number)")
|
||||||
Text("\(chapter.number)")
|
.font(.caption.bold())
|
||||||
.font(.caption.bold())
|
.foregroundStyle(chapter.number == currentChapter ? .white : .secondary)
|
||||||
.foregroundStyle(chapter.number == currentChapter ? .white : .secondary)
|
.frame(width: 44, height: 44)
|
||||||
.frame(width: 44, height: 44)
|
.background(
|
||||||
.background(
|
Circle()
|
||||||
Circle()
|
.fill(chapter.number == currentChapter ? Color.amber : Color.gray.opacity(0.2))
|
||||||
.fill(chapter.number == currentChapter ? Color.amber : Color.gray.opacity(0.2))
|
)
|
||||||
)
|
|
||||||
|
|
||||||
// Chapter title
|
// Chapter title
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
Text(chapter.title.strippingTrailingDate())
|
Text(chapter.title.strippingTrailingDate())
|
||||||
.font(.subheadline.weight(chapter.number == currentChapter ? .semibold : .regular))
|
.font(.subheadline.weight(chapter.number == currentChapter ? .semibold : .regular))
|
||||||
.foregroundStyle(chapter.number == currentChapter ? .primary : .primary)
|
.foregroundStyle(chapter.number == currentChapter ? .primary : .primary)
|
||||||
.lineLimit(2)
|
.lineLimit(2)
|
||||||
|
|
||||||
if chapter.number == currentChapter {
|
|
||||||
Text("Now Playing")
|
|
||||||
.font(.caption2)
|
|
||||||
.foregroundStyle(.amber)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
// Checkmark for current chapter
|
|
||||||
if chapter.number == currentChapter {
|
if chapter.number == currentChapter {
|
||||||
Image(systemName: "checkmark")
|
Text("Now Playing")
|
||||||
.font(.caption.bold())
|
.font(.caption2)
|
||||||
.foregroundStyle(.amber)
|
.foregroundStyle(.amber)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.vertical, 8)
|
|
||||||
}
|
Spacer()
|
||||||
.buttonStyle(.plain)
|
|
||||||
.listRowBackground(
|
// Checkmark for current chapter
|
||||||
chapter.number == currentChapter
|
if chapter.number == currentChapter {
|
||||||
? Color.amber.opacity(0.1)
|
Image(systemName: "checkmark")
|
||||||
: Color.clear
|
.font(.caption.bold())
|
||||||
)
|
.foregroundStyle(.amber)
|
||||||
.id(chapter.number)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
.listStyle(.plain)
|
|
||||||
.onAppear {
|
|
||||||
// Scroll to current chapter on appear
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
||||||
withAnimation {
|
|
||||||
proxy.scrollTo(currentChapter, anchor: .center)
|
|
||||||
}
|
}
|
||||||
|
.padding(.vertical, 8)
|
||||||
}
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
.listRowBackground(
|
||||||
|
chapter.number == currentChapter
|
||||||
|
? Color.amber.opacity(0.1)
|
||||||
|
: Color.clear
|
||||||
|
)
|
||||||
|
.id(chapter.number)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.listStyle(.plain)
|
||||||
|
.scrollPosition(id: $scrollPosition, anchor: .center)
|
||||||
|
.onAppear {
|
||||||
|
// Set initial scroll position without animation
|
||||||
|
scrollPosition = currentChapter
|
||||||
|
}
|
||||||
.navigationTitle("Chapters")
|
.navigationTitle("Chapters")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
|||||||
Reference in New Issue
Block a user