Search code examples
iosarraysgenericsswiftuioffset

How to use a generic array - SwiftUI


Hi I'm creating a component that needs to consider an array for its operation.

I created a model for displaying the array like this

struct FeaturedWorksModel: Identifiable {
    var id = UUID()
    var image: String
    var title: String
}

var featuredWorksItems: [FeaturedWorksModel] = [
    FeaturedWorksModel(image: "slider1", title: "TAGLIO CREATIVO"),
    FeaturedWorksModel(image: "slider4", title: "LOREM IPSUM"),
    FeaturedWorksModel(image: "slider3", title: "NEQUE EST DOLOR"),
    FeaturedWorksModel(image: "slider2", title: "CONSECTETUR, INTEGER ERAT AUGUE ")
]

Now my component can also be used with other arrays and I wanted to know how I can define a generic array within the component initialization parameters in order to reuse the component even referring to arrays other than the one I am using in this moment

This is the component I am using to which I will have to pass the reference array for it to work

struct SmoothPager: View {
    
    @Binding var offset: CGPoint
    
    var body: some View {
        HStack(spacing: 10) {
            ForEach(featuredWorksItems.indices) { works in
                Capsule()
                    .fill(getIndex() == works ? .white : .gray)
                    .frame(width: getIndex() == works ? 15 : 7, height: 7)
            }
            
        }
        .overlay(
        Capsule()
            .fill(.white)
            .frame(width: 15, height: 7)
            .offset(x: getOffset())
        , alignment: .leading
        )
    }
    
    func getIndex()-> Int {
        let index = Int(round(Double(offset.x / screen.width)))
        return index
    }

    func getOffset()-> CGFloat {
        let progress = offset.x / screen.width
        return 17 * progress
    }
}

In this case I am using featuredWorksItems.indices but I wanted to make the component reusable with other similar arrays as well. What is the best way to pass a generic array parameter in this structure?


Solution

  • Do you mean something like

    struct SmoothPager<Element: Identifiable>: View {
      @Binding private var offset: CGPoint
      private let elements: [Element]
    
      init(elements: [Element], offset: Binding<CGPoint>) {
        self.elements = elements
        self._offset = offset
      }
    
      var body: some View {
        HStack(spacing: 10) {
          ForEach(elements.indices) { works in
            Capsule()
              .fill(getIndex() == works ? .white : .gray)
              .frame(width: getIndex() == works ? 15 : 7, height: 7)
          }
    
        }
        .overlay(
          Capsule()
            .fill(.white)
            .frame(width: 15, height: 7)
            .offset(x: getOffset())
          , alignment: .leading
        )
      }
    
      func getIndex()-> Int {
        let index = Int(round(Double(offset.x / UIScreen.main.bounds.width)))
        return index
      }
    
      func getOffset()-> CGFloat {
        let progress = offset.x / UIScreen.main.bounds.width
        return 17 * progress
      }
    }