ScrollView 中的 ScrollTo 无法按预期工作

Posted

技术标签:

【中文标题】ScrollView 中的 ScrollTo 无法按预期工作【英文标题】:ScrollTo in ScrollView not working as expected 【发布时间】:2021-09-22 15:35:46 【问题描述】:

基本滚动视图。当使用 scrollView.scrollTo(value,anchor:.bottom) 的值时,它会滚动。 当用它的值 "99" 替换时,它不会。不确定这是不是有意的。如果不是,想知道如何使用 id 的值而不是从元素的位置检索它。

struct Testchat: View 
    @State private var listMessages: [MessageTest] = []
    @State private var scrolled = false

    var body: some View 
        ScrollViewReader  scrollView in
            ScrollView 
                VStack(spacing: 0) 
                    ForEach(listMessages, id: \.id)  messageInList in
                        Text(messageInList.id)
                            .onAppear 
                                if !scrolled 
                                    let value = listMessages[99].id
                                    scrollView.scrollTo("99",anchor: .bottom)
                                    scrolled = true
                                
                            
                    
                
            
        
        .onAppear 
            for i in 0 ..< 100 
                let messagetest:MessageTest = .init()
                messagetest.id = i.description
                messagetest.message = i.description
                listMessages.append(messagetest)
            
        
    

public class MessageTest: NSObject, Codable, ObservableObject 
    var message: String!
    var id: String!

    public override init() 
        message = "VOID"
        id = "VOID"
    

【问题讨论】:

尝试将.id(messageInList.id) 添加到您的文本中。但除此之外,与其使用String 作为id,不如UUID 更好。 感谢您的回答。这只是更复杂的事情的一个简单的例子。在我的其他情况下,ID 是 firebaseIDs (very long) 。我试图将 .id(id) 添加到视图中,它似乎确实有效。所以我非常感谢你的帮助。滚动在一种情况下工作而不是另一种情况下仍然很奇怪(但这不是第一个奇怪的行为......) 永远不会将类或结构中的属性声明为在 init 方法中初始化的隐式解包可选。不。如果您需要选项,请使用常规选项 (?),否则使用非选项,即使没有感叹号,代码也符合要求。与 UIKit 相比,SwiftUI 更鼓励您尽可能避免使用可选项。 【参考方案1】:

在您的ForEach 中,您通过\.id 键路径识别每一行。 MessageTest 中的 id 属性是可选的,类型为 String!(但实际上是 String?,表示 Optional&lt;String&gt;)。

因此,您需要将滚动到的行作为String? 类型传递,而不仅仅是String

通过添加演员表将行更改为以下内容:

scrollView.scrollTo("99" as String?, anchor: .bottom)

将here 链接到关于String?String!Optional&lt;String&gt; 的答案,但! 版本只是隐式强制解包。

【讨论】:

您好,谢谢您的回答。这些“细节”需要高级的 ios 知识。所以演员表工作了。没有转换为字符串? ,将 .id(id) 添加到视图中,如 aheze 所示也有效。我想这种特殊情况可能会对某人有所帮助。谢谢 @it75 这并不是真正的 iOS 高级知识,它只是 SwiftUI 框架的工作原理。基本上在使用ScrollViewReader 时,每个视图的id 的类型需要与您scrollTo 的类型相同。这就是为什么我们必须强制转换为String?,所以类型是相同的。像这样设置一个显式的.id(...) 也有效,因为现在你只是给它一个String,就像"99" 是一个String

以上是关于ScrollView 中的 ScrollTo 无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

使用开源的PullToRefreshScrollView scrollTo和scrollby遇到的问题

如何滚动到scrollview内recyclerview中的特定位置?

Android 如何在进入有scrollView的页面时滑动条置顶

Android控制ScrollView滚动

Android 控制ScrollView滚动到底部

Android 控制ScrollView滚动到底部