xcode 如何在macOS下使用SwiftUI使List滚动以显示后台Array of String中的最后一行

c2e8gylq  于 2023-04-22  发布在  Mac
关注(0)|答案(1)|浏览(147)

我已经尝试了几个解决方案,但没有一个对我有效,大多数都是冗长的编译错误,我不知道如何修复。我今天与AI合作,在第三次迭代后编辑了这个紧凑的解决方案,编译-但列表仍然不能自动滚动。我在Swift中非常,非常新。
String的backing Array由已发布的observableObject更新:

class Logger: ObservableObject {
    
    @Published var messageArray = ["Start by selecting the project's data folder."]
    
    func addMessage(_ msg: String) {
        messageArray.append("\(timeNow()) *  \(msg)")
    }

我在我的主(且唯一的)ContentView中创建一个示例

@ObservedObject var logger = Logger()

下面的代码在VStack中,当messageArray被其他代码更改时,它会更新,但不会滚动。它适用于macOS而不是IOS

List(logger.messageArray, id: \.self) {
        message in
        Text(message)
    }
    .padding()
    .background(ScrollViewReader { proxy in
        Color.clear.onAppear {
            proxy.scrollTo(logger.messageArray.last)
        }
        .onReceive(logger.$messageArray) { _ in
            withAnimation {
                proxy.scrollTo(logger.messageArray.last)
            }
        }
    })

我希望你能帮助我,因为我已经花了太多的时间。

vmjh9lq9

vmjh9lq91#

你可以尝试这种方法,滚动到列表的最后一行。它使用了重要的id.onChange(),并使用ScrollViewReader Package List。对我来说很有效。

class Logger: ObservableObject {
    
    @Published var messageArray = ["message"]
    
    func addMessage(_ msg: String) {
        messageArray.append("\(UUID().uuidString.prefix(5)) *  \(msg)") // <-- for testing
    }
    
}

struct ContentView: View {
    @StateObject var logger = Logger() // <-- here
    
    var body: some View {
        ScrollViewReader { proxy in
            List (logger.messageArray, id: \.self) { message in
                Text(message).id(message) // <-- here, need id
            }
            .onChange(of: logger.messageArray) { _ in    // <-- here
                withAnimation {
                    proxy.scrollTo(logger.messageArray.last)
                }
            }
            .padding()
        }
        Button("Add message") {
            logger.addMessage("test message")  // <-- for testing
        }
    }
    
}

相关问题