双向垂直滚动视图(在顶部/底部动态添加项目)在添加到列表开头时不会干扰滚动位置 [英] Infinite vertical scrollview both ways (add items dynamically at top/bottom) that doesn’t interfere with scroll position when you add to list start

查看:94
本文介绍了双向垂直滚动视图(在顶部/底部动态添加项目)在添加到列表开头时不会干扰滚动位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是垂直滚动视图,双向滚动视图是无限的:向上滚动到顶部或向下滚动到底部将导致动态添加更多项.我遇到的几乎所有帮助都只涉及到范围的无限广度.我确实遇到了

解决方案

戳代码后,我相信您所看到的这种跳动是由以下原因引起的:

  DispatchQueue.main.asyncAfter(截止日期:.now()+ 0.4){withAnimation(.easeIn){items.insert(items.first!-1,at:0)}} 

如果您将两者都删除,仅保留 items.insert(items.first!-1,at:0),跳动将停止.

I’m after a vertical scrollview that’s infinite both ways: scrolling up to the top or down to the bottom results in more items being added dynamically. Almost all help I’ve encountered is only concerned with the bottom side being infinite in scope. I did come across this relevant answer but it’s not what I’m specifically looking for (it’s adding items automatically based on time duration, and requires interaction with direction buttons to specify which way to scroll). This less relevant answer however has been quite helpful. Based on the suggestion made there, I realised I can keep a record of items visible at any time, and if they happen to be X positions from the top/bottom, to insert an item at the starting/ending index on the list.

One other note is I’m getting the list to start in the middle, so there’s no need to add anything either way unless you’ve moved 50% up/down.

To be clear, this is for a calendar screen that I want the user to be scroll to any time freely.

    struct TestInfinityList: View {
    
    @State var visibleItems: Set<Int> = []
    @State var items: [Int] = Array(0...20)
    
    var body: some View {
        ScrollViewReader { value in
        
            List(items, id: \.self) { item in
                VStack {
                    Text("Item \(item)")
                }.id(item)
                .onAppear {
                    self.visibleItems.insert(item)
                    
                    /// if this is the second item on the list, then time to add with a short delay
                    /// another item at the top
                    if items[1] == item {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
                            withAnimation(.easeIn) {
                                items.insert(items.first! - 1, at: 0)
                            }
                        }
                    }
                }
                .onDisappear {
                    self.visibleItems.remove(item)
                }
                .frame(height: 300)
            }
            .onAppear {
                value.scrollTo(10, anchor: .top)
            }
        }
    }
}

This is mostly working fine except for a small but important detail. When an item is added from the top, depending on how I’m scrolling down, it can sometimes be jumpy. This is most noticeable towards the end of clip attached.

解决方案

After poking at your code I believe that this jumpiness that you're seeing is caused by this:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
    withAnimation(.easeIn) {
        items.insert(items.first! - 1, at: 0)
    }
}

If you remove both and only leave items.insert(items.first! - 1, at: 0) the jumpiness will stop.

这篇关于双向垂直滚动视图(在顶部/底部动态添加项目)在添加到列表开头时不会干扰滚动位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆