SwiftUI: onChange with @Binding from outside view

.onChange is not going to get called cause MainTextView doesn't exist when showingToc = true because of the conditional block:

if showingToc {
  TableOfContentsView(onChapterSelected: { chapter in
      scrollPosition = chapter
      showingToc = false
    }
  )
} else {
  MainTextView(scrollPosition: $scrollPosition)
}

You might want to consider showing TOC as an overlay. But to get your current code working, you need to call proxy.scrollTo in your .onAppear of MainTextView:

.onAppear {
  scrollProxy = proxy
  scrollProxy?.scrollTo(scrollPosition, anchor: .top)
}