I am trying to add arrows to a scrollView in SwiftUI. When the app is open or all the way to the left side there is an arrow pointing to the right:
and the opposite when it reaches the right side:
What I am struggling with is how to have both arrows to appear when the person is scrolling.
I am able to get the arrows to appear when I am between point A and B, but when I reach either end the double arrows remains, instead of the single arrow I want when it reaches either end of the scrollView.
So what I want is and arrow showing which direction the scroll can do, so when it can't scroll to anyone side anymore, like when it reaches the far left or right, there is only one arrow, but when the scrolling can be either direction there are two arrows, that disappear when it reaches either end.
I am able to get the arrows working when they reach either side, but I was hoping for the double arrows when it is needed. I think there must be something to determine when scrolling is being done.
I have looked at a few sources to get to where I am now, and things I have tried before, to no avail:
Video: https://www.youtube.com/watch?v=h47UkS8pLA8
https://developer.apple.com/forums/thread/650312
Interaction of DragGesture and ScrollView in SwiftUI
In SwiftUI, where are the control events, i.e. scrollViewDidScroll to detect the bottom of list data
This is the main View:
import SwiftUI
enum scrollingEnum {
case leading
case scrolling
case trailing
}
struct ContentView: View {
@State private var defaultX: CGFloat = 0.0
@State private var leadingBool: Bool = false
@State private var trailingBool: Bool = true
@State private var scrolling: scrollingEnum = .leading
var body: some View {
VStack {
ScrollView(.horizontal) {
GeometryReader { geo in
Rectangle()
.frame(width: 0, height: 0)
.onAppear(perform: {
defaultX = geo.frame(in: .global).midX
})
.onChange(of: geo.frame(in: .global).midX) { midX in
switch scrolling {
case .leading:
leadingBool = false
trailingBool = true
case .trailing:
leadingBool = true
trailingBool = false
case .scrolling:
leadingBool = true
trailingBool = true
}
if defaultX > midX {
scrolling = .scrolling
}
}
}
.frame(width: 0, height: 0)
.border(Color.red)
LazyHStack {
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.green)
.padding()
.onAppear {
scrolling = .leading
}
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.blue)
.padding()
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.red)
.padding()
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.purple)
.padding()
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.orange)
.padding()
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.green)
.padding()
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.blue)
.padding()
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.red)
.padding()
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.purple)
.padding()
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(20)
.foregroundColor(.orange)
.padding()
.onAppear {
scrolling = .trailing
}
}
}
.overlay {
ArrowUIView(leadingBool: leadingBool, trailingBool: trailingBool)
}
}
}
}
This is the view for the arrows:
import SwiftUI
struct ArrowUIView: View {
var leadingBool: Bool
var trailingBool: Bool
var body: some View {
HStack {
if leadingBool {
Image(systemName: "arrow.left.circle.fill")
.resizable()
.frame(width: 50, height: 50)
.opacity(0.5)
}
Color.clear
if trailingBool {
Image(systemName: "arrow.right.circle.fill")
.resizable()
.frame(width: 50, height: 50)
.opacity(0.5)
}
}
}
}
If there is anything else I can answer please ask, thank you.