19.3 C
Canberra
Thursday, November 13, 2025

Swiftui LazyVStack subject on iOS 17, 18


I am unable to determine why the LazyVStack will not snap again typically after dismissing the keyboard. There’s 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 subject arises.

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

Swiftui LazyVStack subject 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(Colour.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 #out there(iOS 17.0, *) {
            Textual content("Chat")
                .body(width: UIScreen.fundamental.bounds.width, top: 70)
                .padding(.prime, 20)
                .safeAreaPadding(.prime)
                .background(Colour.pink.opacity(0.5))
                .clipShape(Rectangle())
            
        } else {
            Textual content("Chat")
                .body(top: 70)
                .background(Colour.pink.opacity(0.5))
                .clipShape(Rectangle())
                .padding(.prime, 20)
        }    }
}

// MARK: - Messages Listing
struct MessagesList: View {
    var messages: [ChatMessage]
    @Binding var scrollToID: Int?
    
    var physique: some View {
        if #out there(iOS 17.0, *) {
            ScrollView {
                LazyVStack(spacing: 14) {
                    ForEach(messages, id: .id) { msg in
                        MessageBubble(message: msg)
                    }
                }
                .padding(.vertical)
                .background(Colour.yellow.opacity(0.5))
            }
            .background(Colour.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(Colour.white)
                .clipShape(RoundedRectangle(cornerRadius: 10))
            
            Button(motion: onSend) {
                Textual content("Ship")
                    .foregroundColor(.white)
                    .padding(.vertical, 10)
                    .padding(.horizontal, 16)
                    .background(Colour.blue)
                    .clipShape(RoundedRectangle(cornerRadius: 10))
            }
        }
        .padding(.horizontal)
        .padding(.backside, 12)
        .background(Colour.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 ? Colour.black : Colour.white)
                .clipShape(RoundedRectangle(cornerRadius: 14))
                .body(maxWidth: UIScreen.fundamental.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

[td_block_social_counter facebook="tagdiv" twitter="tagdivofficial" youtube="tagdiv" style="style8 td-social-boxed td-social-font-icons" tdc_css="eyJhbGwiOnsibWFyZ2luLWJvdHRvbSI6IjM4IiwiZGlzcGxheSI6IiJ9LCJwb3J0cmFpdCI6eyJtYXJnaW4tYm90dG9tIjoiMzAiLCJkaXNwbGF5IjoiIn0sInBvcnRyYWl0X21heF93aWR0aCI6MTAxOCwicG9ydHJhaXRfbWluX3dpZHRoIjo3Njh9" custom_title="Stay Connected" block_template_id="td_block_template_8" f_header_font_family="712" f_header_font_transform="uppercase" f_header_font_weight="500" f_header_font_size="17" border_color="#dd3333"]
- Advertisement -spot_img

Latest Articles