jarv
jarv

Reputation: 11

Keep scroll position when new items are added to top of the list

I am having an issue with keeping the list view 'frozen' in place when new items are added if the user has scrolled down to view and item. Here is the code that I am currently using:

import SwiftUI

struct MessageList: View {
    @ObservedObject var socketManager: WebSocketManager
    @State var isUpdating: Bool = false
    @State private var currentOffset: CGFloat = 0
    @State private var currentScrollID: UUID?
    
    @State private var timer: Timer? = nil
    
    func simulateMessages(){
        timer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { _ in
            let newItem = Message(content: "Hello", sentFlag: true)
            socketManager.messages.append(newItem)
        }
    }
    
    func stopSimulation(){
        timer?.invalidate()
        timer = nil
    }
    
    var body: some View {
        Button{
            if isUpdating{
                stopSimulation()
            } else {
                simulateMessages()
            }
            
            isUpdating.toggle()
            
        } label: {
            Text(isUpdating ? "Stop" : "Update")
        }
        
        List(socketManager.messages.reversed(), id: \.uuid) { message in
            messageView(message: message)
                .swipeActions(edge: .trailing) {
                    DeleteButton(socketManager: socketManager, message: message)
                }
                .swipeActions(edge: .leading){
                    SaveButton(socketManager: socketManager, message: message)
                }
                .contextMenu{
                    SaveButton(socketManager: socketManager, message: message)
                    DeleteButton(socketManager: socketManager, message: message)
                }
        }

    }
}
#Preview {
    let socketManager = {
        let manager = WebSocketManager()
        manager.messages = [Message(content: "Hello, World! \nthis is a long message \nThis \nnew line\na\nb\nc\nd", sentFlag: true),
                            Message(content: "Hello, World! \nthis is a long message \nThis \nnew line\na\nb\nc\nd", sentFlag: false)]
        return manager
    }()
    MessageList(socketManager: socketManager)
}

I experimented with this solution. However, this uses a lazyVStack and I would like to keep the list if possible for styling and the swipe actions.

Upvotes: 1

Views: 28

Answers (0)

Related Questions