HomeiOS DevelopmentSwiftui LazyVStack problem on iOS 17, 18

Swiftui LazyVStack problem on iOS 17, 18


I can not work out why the LazyVStack will not snap again typically after dismissing the keyboard. There may be one factor I understood that’s when measurement of the views contained in the LazyVStack are identical there will not be any points however when measurement varies this problem arises.

Lazy is in background yellow and scrollview is in inexperienced. Simply put it like that to point out my problem clearly.

Swiftui LazyVStack problem on iOS 17, 18

struct MessagesView: View {
    @State non-public var messages: [ChatMessage] = MockChatMessages().loadAllMessages()
    @State non-public var inputText: String = ""
    @Binding var showChat: Bool
    
    @State non-public var scrollToID: Int?     // Used for iOS 17 auto-scroll
    
    var physique: some View {
        VStack(spacing: 0) {
            HeaderView()
            MessagesList(messages: messages, scrollToID: $scrollToID)
            InputBar(inputText: $inputText, onSend: sendMessage)
        }
        .background(Shade.blue.opacity(0.3))
        .ignoresSafeArea(edges: .prime)
        .onAppear {
            scrollToID = messages.final?.id
        }
        .onChange(of: messages.depend) { _ in
            scrollToID = messages.final?.id
        }
    }
}

// MARK: - Header
struct HeaderView: View {
    var physique: some View {
        if #obtainable(iOS 17.0, *) {
            Textual content("Chat")
                .body(width: UIScreen.important.bounds.width, peak: 70)
                .padding(.prime, 20)
                .safeAreaPadding(.prime)
                .background(Shade.pink.opacity(0.5))
                .clipShape(Rectangle())
            
        } else {
            Textual content("Chat")
                .body(peak: 70)
                .background(Shade.pink.opacity(0.5))
                .clipShape(Rectangle())
                .padding(.prime, 20)
        }    }
}

// MARK: - Messages Checklist
struct MessagesList: View {
    var messages: [ChatMessage]
    @Binding var scrollToID: Int?
    
    var physique: some View {
        if #obtainable(iOS 17.0, *) {
            ScrollView {
                LazyVStack(spacing: 14) {
                    ForEach(messages, id: .id) { msg in
                        MessageBubble(message: msg)
                    }
                }
                .padding(.vertical)
                .background(Shade.yellow.opacity(0.5))
            }
            .background(Shade.inexperienced.opacity(0.5))
            .scrollIndicators(.hidden)
            .scrollPosition(id: $scrollToID, anchor: .backside)
        } else {
            ScrollViewReader { proxy in
                ScrollView {
                    LazyVStack(spacing: 14) {
                        ForEach(messages, id: .id) { msg in
                            MessageBubble(message: msg)
                                .id(msg.id)
                        }
                    }
                    .padding(.vertical)
                }
                .onChange(of: scrollToID) { id in
                    if let id = id {
                        withAnimation {
                            proxy.scrollTo(id, anchor: .backside)
                        }
                    }
                }
            }
        }
    }
}

// MARK: - Enter Bar
struct InputBar: View {
    @Binding var inputText: String
    var onSend: () -> Void
    
    var physique: some View {
        HStack {
            TextField("Kind your message...", textual content: $inputText)
                .padding(12)
                .background(Shade.white)
                .clipShape(RoundedRectangle(cornerRadius: 10))
            
            Button(motion: onSend) {
                Textual content("Ship")
                    .foregroundColor(.white)
                    .padding(.vertical, 10)
                    .padding(.horizontal, 16)
                    .background(Shade.blue)
                    .clipShape(RoundedRectangle(cornerRadius: 10))
            }
        }
        .padding(.horizontal)
        .padding(.backside, 12)
        .background(Shade.grey.opacity(0.15))
    }
}

// MARK: - Single Message Bubble
struct MessageBubble: View {
    var message: ChatMessage
    
    var isRight: Bool { message.path == .proper }
    
    var physique: some View {
        HStack {
            if isRight { Spacer() }
            
            Textual content(message.message)
                .foregroundColor(isRight ? .white : .black)
                .padding(.vertical, 10)
                .padding(.horizontal, 12)
                .background(isRight ? Shade.black : Shade.white)
                .clipShape(RoundedRectangle(cornerRadius: 14))
                .body(maxWidth: UIScreen.important.bounds.width * 0.7, alignment: isRight ? .trailing : .main)
            
            if !isRight { Spacer() }
        }
        .padding(.horizontal, 12)
    }
}

// MARK: - Add Message Perform
extension MessagesView {
    func sendMessage() {
        guard !inputText.isEmpty else { return }
        
        let nextID = (messages.final?.id ?? 0) + 1
        
        let msg = ChatMessage(
            id: nextID,
            path: .proper,
            message: inputText
        )
        
        messages.append(msg)
        inputText = ""
        scrollToID = msg.id
    }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments