Post

Replies

Boosts

Views

Activity

Reply to ScrollViewReader's scrollTo may be broken on iOS 15
Found a workaround that works for me on both OSX and iOS. I suspected the bug was happening from scrollTo() incorrectly calculating the offset of the particular view in the reference frame of the scrollview, as I was getting different scroll positions depending on how far down the list the scrollTo view was. Previously the scrollview content was composed of different container views, with subviews inside those. The workaround was to flatten those container views so the requested view IDs to scrollTo are all flat at the top level of the scroll view content. ScrollView setup: ScrollViewReader { proxy in         GeometryReader { geometry in             ScrollView(showsIndicators: false) {                 VStack(alignment: .leading, spacing: 17) {                     ForEach(levelSelect.worlds) { world in                         flatRowItems(world: world)                     }                 }             }             .onAppear {                 if let id = levelSelect.selectedLevelID {                     proxy.scrollTo(id, anchor: .center)                 }             }             .onChange(of: levelSelect.selectedLevelID) { selectedLevelID in                 guard let selectedLevelID = selectedLevelID else { return }                 if !levelSelect.isInitialSelection {                     withAnimation {                         proxy.scrollTo(selectedLevelID, anchor: nil)                     }                 } else {                     levelSelect.isInitialSelection = false                     proxy.scrollTo(selectedLevelID, anchor: .center)                 }             }         }     } Flattened scrollview content using @ViewBuilder: @ViewBuilder func flatRowItems(world: World) -> some View {         Group { // previously had a WorldRow which contained the following content as child views             if world.locked {                 LockedWorldRow(world: world)             } else {                 UnlockedWorldRow(world: world) // previously UnlockedWorldRow contained LevelRows inside                 ForEach(world.levels) { level in                     LevelRow(levelItem: level)                     .id(level.id)                 }             }         }     }
Dec ’21