0

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:

enter image description here

and the opposite when it reaches the right side:

enter image description here

What I am struggling with is how to have both arrows to appear when the person is scrolling.

enter image description here

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.

Yo19
  • 223
  • 2
  • 16

0 Answers0