I implemented a scollview with the following code.
And the "Stopped on: \($0)"
is never called. Did i do something wrong?
func scrollableView(with geometryProxy: GeometryProxy) -> some View {
let middleScreenPosition = geometryProxy.size.height / 2
return ScrollView(content: {
ScrollViewReader(content: { scrollViewProxy in
VStack(alignment: .leading, spacing: 20, content: {
Spacer()
.frame(height: geometryProxy.size.height * 0.4)
ForEach(viewModel.fragments, id: \.id) { fragment in
Text(fragment.content) // Outside of geometry ready to set the natural size
.opacity(0)
.overlay(
GeometryReader { textGeometryReader in
let midY = textGeometryReader.frame(in: .global).midY
Text(fragment.content) // Actual text
.font(.headline)
.foregroundColor( // Text color
midY > (middleScreenPosition - textGeometryReader.size.height / 2) &&
midY < (middleScreenPosition + textGeometryReader.size.height / 2) ? .white :
midY < (middleScreenPosition - textGeometryReader.size.height / 2) ? .gray :
.gray
)
.colorMultiply( // Animates better than .foregroundColor animation
midY > (middleScreenPosition - textGeometryReader.size.height / 2) &&
midY < (middleScreenPosition + textGeometryReader.size.height / 2) ? .white :
midY < (middleScreenPosition - textGeometryReader.size.height / 2) ? .gray :
.clear
)
.animation(.easeInOut)
}
)
.scrollId(fragment.id)
}
Spacer()
.frame(height: geometryProxy.size.height * 0.4)
})
.frame(maxWidth: .infinity)
.background(GeometryReader {
Color.clear.preference(key: ViewOffsetKey.self,
value: -$0.frame(in: .named("scroll")).origin.y)
})
.onPreferenceChange(ViewOffsetKey.self) { detector.send($0) }
.padding()
.onReceive(self.fragment.$currentFragment, perform: { currentFragment in
guard let id = currentFragment?.id else {
return
}
scrollViewProxy.scrollTo(id, alignment: .center)
})
})
})
.simultaneousGesture(
DragGesture().onChanged({ _ in
print("Started Scrolling")
}))
.coordinateSpace(name: "scroll")
.onReceive(publisher) {
print("Stopped on: \($0)")
}
}
I am not sure if I should do a new Stack post or not here, since I am trying to make the code here works.
Edit: Actually it works if I paused the audio player playing at the same time. By pausing it, it allows the publisher to be called.
Awkward.
Edit 2: removing .dropFirst()
seems to fix it but over calling it.