简体   繁体   English

如何检查项目是否可见 - SwiftUI ScrollView

[英]How to check if item is visible - SwiftUI ScrollView

Trying to programmatically determine when an item is being displayed on screen in a ScrollView in SwiftUI.尝试以编程方式确定项目何时在 SwiftUI 的 ScrollView 中显示在屏幕上。 I understand that a ScrollView renders at one time rather than rendering as items appear (like in List), but I am constrained to using ScrollView as I have.scrollTo actions.我知道 ScrollView 一次呈现,而不是在项目出现时呈现(如在 List 中),但我受限于使用 ScrollView,因为我有 .scrollTo 操作。

I also understand that in UIKit with UIScrollView, it is possible to use a CGRectIntersectsRect between the item frame and the ScrollView frame in the UIScrollViewDelegate but I would prefer to find a solution in SwiftUI if possible.我也明白在 UIKit 和 UIScrollView 中,可以在 UIScrollViewDelegate 中的项目框架和 ScrollView 框架之间使用 CGRectIntersectsRect 但如果可能的话,我更愿意在 Z5D807DF8E2D0F6DFCC09ZB503 中找到解决方案。

Example code looks like this:示例代码如下所示:

ScrollView {
    ScrollViewReader { action in
        ZStack {
            VStack {
                ForEach(//array of chats) { chat in
                    //chat display bubble
                        .onAppear(perform: {chatsOnScreen.append(chat)})
                }.onReceive(interactionHandler.$activeChat, perform: { _ in
                    //scroll to active chat
                })
            }
        }
    }
}

Ideally, when a user scrolls, it would check which items are on screen and zoom the view to fit the largest item on screen.理想情况下,当用户滚动时,它会检查哪些项目在屏幕上并缩放视图以适应屏幕上最大的项目。

When you use VStack in ScrollView all content is created at once at build time, so onAppear does not fit your intention, instead you should use LazyVStack , which will create each subview only before it appears on screen, so onAppear will be called when you expect it.当您在ScrollView中使用VStack时,所有内容都是在构建时一次创建的,因此onAppear不符合您的意图,相反您应该使用LazyVStack ,它只会在每个子视图出现在屏幕上之前创建它,因此onAppear将在您期望的时候被调用它。

So it should be like所以它应该像

ScrollViewReader { action in
   ScrollView {
        LazyVStack {                              // << this !!
            ForEach(//array of chats) { chat in
                //chat display bubble
                    .onAppear(perform: {chatsOnScreen.append(chat)})
            }.onReceive(interactionHandler.$activeChat, perform: { _ in
                //scroll to active chat
            })
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM