Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
[ad_1]
What I need
I’ve a “ScrollView” in a customized sheet that I can drag down to shut. After all, the ScrollView
is above the drag space, so after I drag over the ScrollView
it scrolls down or up. I wish to disable the ScrollView when I’m on the high of the ScrollView
and scroll up in order that the sheet is dragged and begins to shut. That is just like the behaviour of the Shazam sheet.
The Drawback
If the ScrollView
is deactivated, the present drag motion just isn’t utilized to the sheet, however does nothing. Solely when dragging once more (on the now deactivated ScrollView
) the sheet is concentrated on the dragging. So is there a approach to switch the main target of the drag motion from the ScrollView
to the outer sheet view with out beginning a brand new one?
Showcase
I created a simplified model of the issue for higher understanding.
We’ve a container (inside
) that’s draggable alongside the y-axis. On drag launch, we let it bounce again to offset 0.
@State var offsetY: CGFloat = .zero
var physique: some View {
Interior(outerOffset: $offsetY)
.offset(y: offsetY)
.gesture(DragGesture().onChanged { worth in
offsetY = worth.translation.peak
}.onEnded { _ in
offsetY = 0
}
)
}
Contained in the container now we have our personal ScrollView (ScrollViewOffset
) which takes a callback with the present scroll offset. If the offset is optimistic (i.e. if we’re scrolling upwards, even when we’re on the high of the content material), we wish to disable the scroll and let the outer container drag alongside the y-axis as a substitute of the ScrollView
. To activate the ScrollView
we pay attention for the outerOffset
(the drag worth) and activate the ScrollView
when the offset is 0
once more (this occurs when releasing the drag as described earlier than).
struct Interior: View {
@Binding var outerOffset: CGFloat
@State var disableScroll = false
var physique: some View {
ScrollViewReader { proxy in
ScrollViewOffset {
ForEach(0 ... 10, id: .self) { e in
Textual content(String(e))
.id(e)
.padding()
Divider()
}
} onOffsetChange: { offset in
if offset > 0 {
disableScroll = true
}
}
.background(.purple)
.padding()
.body(width: nil, peak: 400)
.onChange(of: outerOffset) { _ in
if outerOffset == 0 {
proxy.scrollTo(0)
disableScroll = false
}
}
.disabled(disableScroll)
}
}
}
Once we run this, it’s straightforward to see the issue I discussed earlier than. The ScrollView
is getting disabled because it ought to, however the container just isn’t centered on the drag. Solely after beginning a brand new drag, the container is concentrated.
My precise case
Final however not least the shazam equal (left) and my undertaking (proper).
[ad_2]