Saturday, January 6, 2024
HomeiOS Developmentios - Why is my looping scrollview leaping round?

ios – Why is my looping scrollview leaping round?


I am attempting to make a horizontal scrollview that loops. All of the options I’ve discovered on-line for this drawback embody including copies of things at the start or finish of the record. The ingredient(s) inside have state and their look adjustments primarily based on that state.

The issue is that when reaching the tip, the following (first) merchandise is caught with its preliminary state slightly than the present state. This leads to jerky conduct: display recording

I’ve tried this with each instance I’ve discovered on-line with very related outcomes every time. The instance within the video is made with the next code, though yow will discover the bare-bones instance right here: Github

struct InfiniteHorizontalScrollView2<Content material: View, Merchandise: RandomAccessCollection>: View the place Merchandise.Ingredient: Identifiable {
    var width: CGFloat
    var gadgets: Merchandise
    var repeatingCount = 1
    @ViewBuilder var content material: (Merchandise.Ingredient) -> Content material
    
    var physique: some View {
        ScrollView(.horizontal) {
            LazyHStack(spacing: 0) {
                ForEach(gadgets) { merchandise in
                    content material(merchandise)
                }
                
                ForEach(0..<repeatingCount, id: .self) { index in
                    let merchandise = Array(gadgets)[index % items.count]
                    content material(merchandise)
                }
            }
            .background {
                ScrollViewHelper(
                    width: width,
                    itemsCount: gadgets.rely
                )
            }
        }
    }
}

struct ScrollViewHelper: UIViewRepresentable {
    var width: CGFloat
    var itemsCount: Int
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(
            width: width,
            itemsCount: itemsCount
        )
    }
    
    func makeUIView(context: Context) -> some UIView {
        return .init()
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {
        DispatchQueue.most important.asyncAfter(deadline: .now() + 0.06) {
            if let scrollView = uiView.superview?.superview?.superview as? UIScrollView, !context.coordinator.isAdded {
                scrollView.delegate = context.coordinator
                context.coordinator.isAdded = true
            }
        }
    }
    
    class Coordinator: NSObject, UIScrollViewDelegate {
        var width: CGFloat
        var itemsCount: Int
        
        init(
            width: CGFloat,
            itemsCount: Int
        ) {
            self.width = width
            self.itemsCount = itemsCount
        }
        
        var isAdded: Bool = false
        
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            let minX = scrollView.contentOffset.x
            let mainContentSize = CGFloat(itemsCount) * width
            
            if minX > mainContentSize {
                scrollView.contentOffset.x -= mainContentSize
            }
            
            if minX < 0 {
                scrollView.contentOffset.x += mainContentSize
            }
        }
    }
}



Supply hyperlink

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments