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:
Admin
2026-03-08 13:34:33 +05:00
parent 825fb04c0d
commit 0df45de2b6

View File

@@ -721,70 +721,66 @@ struct ChaptersListSheet: View {
let onChapterSelect: (Int) -> Void
@Environment(\.dismiss) private var dismiss
@State private var scrollPosition: Int?
var body: some View {
NavigationStack {
ScrollViewReader { proxy in
List {
ForEach(chapters, id: \.number) { chapter in
Button {
onChapterSelect(chapter.number)
} label: {
HStack(spacing: 12) {
// Chapter number badge
Text("\(chapter.number)")
.font(.caption.bold())
.foregroundStyle(chapter.number == currentChapter ? .white : .secondary)
.frame(width: 44, height: 44)
.background(
Circle()
.fill(chapter.number == currentChapter ? Color.amber : Color.gray.opacity(0.2))
)
List {
ForEach(chapters, id: \.number) { chapter in
Button {
onChapterSelect(chapter.number)
} label: {
HStack(spacing: 12) {
// Chapter number badge
Text("\(chapter.number)")
.font(.caption.bold())
.foregroundStyle(chapter.number == currentChapter ? .white : .secondary)
.frame(width: 44, height: 44)
.background(
Circle()
.fill(chapter.number == currentChapter ? Color.amber : Color.gray.opacity(0.2))
)
// Chapter title
VStack(alignment: .leading, spacing: 4) {
Text(chapter.title.strippingTrailingDate())
.font(.subheadline.weight(chapter.number == currentChapter ? .semibold : .regular))
.foregroundStyle(chapter.number == currentChapter ? .primary : .primary)
.lineLimit(2)
// Chapter title
VStack(alignment: .leading, spacing: 4) {
Text(chapter.title.strippingTrailingDate())
.font(.subheadline.weight(chapter.number == currentChapter ? .semibold : .regular))
.foregroundStyle(chapter.number == currentChapter ? .primary : .primary)
.lineLimit(2)
if chapter.number == currentChapter {
Text("Now Playing")
.font(.caption2)
.foregroundStyle(.amber)
}
}
Spacer()
// Checkmark for current chapter
if chapter.number == currentChapter {
Image(systemName: "checkmark")
.font(.caption.bold())
Text("Now Playing")
.font(.caption2)
.foregroundStyle(.amber)
}
}
.padding(.vertical, 8)
}
.buttonStyle(.plain)
.listRowBackground(
chapter.number == currentChapter
? Color.amber.opacity(0.1)
: Color.clear
)
.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)
Spacer()
// Checkmark for current chapter
if chapter.number == currentChapter {
Image(systemName: "checkmark")
.font(.caption.bold())
.foregroundStyle(.amber)
}
}
.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")
.navigationBarTitleDisplayMode(.inline)
.toolbar {