'RoundedRectangle background colour does not crop and TextEditor transparent background

I have a messaging interface. When user types in to the texteditor it will be append to messagesDBArray and will be displayed in textview. Once new messages are there it should scroll to the bottom. But I'm having issues.

Errors: no errors

  1. RoundedRectangle background colour green overflows from corners (does not crop as rounded)
  2. TextEditor (not textview) is not transparent (so it can have rounded rectangle color underneath)
  3. proxy.scrollTo(id, anchor: .bottom) does not scrolls to the last message.
import SwiftUI
    
final class ViewModel: ObservableObject {
    @Published var messagesDBArray : [SingleMessageBubbleModel] = []
}
    
struct SingleMessageBubbleModel: Identifiable {
    let id = UUID()
    var text: String
    var received: Bool
    var timeStamp: Date
}
    
var messagesDBArray : [SingleMessageBubbleModel] = []
    
struct ContentView: View {
    @ObservedObject private var messageArrayObservedObject = ViewModel()
        
    @State private var showOnTheSpotMessaging: Bool = true
    @State var textTyped: String = ""
        
    var body: some View {
    VStack (alignment: .center) {    
        ZStack (alignment: .center) {      
            HStack () {
                RoundedRectangle(cornerRadius: 25, style: .continuous)
                    .stroke(Color.brown, lineWidth: 1)
                    .frame(width: 300, alignment: Alignment.top )
                    .padding([.bottom], 5)
                    .clipped()
                    .background(Color.green)        
            }
            HStack () {
                ScrollViewReader { proxy in
                    ScrollView {
                        LazyVStack {
                            ForEach(
                                messageArrayObservedObject.messagesDBArray,
                                id: \.id
                            ) {
                                message in MessageBubble(message: message)
                            }
                        }
                    }
                    .frame(alignment: .center)
                    .background(Color.clear)
                    .padding (.vertical, 5)
                    .padding (.horizontal,5)
                    .padding(.bottom, 5)
                    
                    .onChange(
                        of: messageArrayObservedObject.messagesDBArray.count
                    ) { id in
                        // When the lastMessageId changes, scroll to the bottom of the conversation
                        withAnimation {
                            proxy.scrollTo(id, anchor: .bottom)
                        }
                    }
                }
                .frame( height: 200, alignment: .center)
            }
            .frame(width: 295, alignment: Alignment.center )  
        } 
        HStack () {
            VStack {    
                ZStack (alignment: .center) {
                    HStack () {
                        RoundedRectangle(cornerRadius: 25, style: .continuous)
                            .stroke(Color.brown , lineWidth: 1)
                            .frame(width: 295, alignment: Alignment.top )
                            .padding([.bottom], 5)
                            .clipped()
                            .background(Color.green)
                            // .background(Color("#E5F2E4"))
                    }
                    HStack () {
                        TextEditor (text: $textTyped)
                            .frame(height: 200, alignment: .leading)
                            .padding(.horizontal, 10)
                            .background(.clear)
                        }
                    }
                    .frame(width: 290, alignment: Alignment.top )
                    .padding(.top, 5)
                }
            }   
        }
    }
    struct MessageBubble: View {
        var message: SingleMessageBubbleModel
        @State private var showTime = false
        
        var body: some View {
            VStack(alignment: message.received ? .leading : .trailing) {
                HStack {
                    Text(message.text)
                        .padding()
                        .background(message.received ? Color.gray : Color.blue)
                        .cornerRadius(30)
                }
                .frame(maxWidth: 300, alignment: message.received ? .leading : .trailing)
                .onTapGesture {
                    withAnimation {
                    showTime.toggle()
                }
            }  
        }
        .frame(maxWidth: .infinity, alignment: message.received ? .leading : .trailing)
        .padding(message.received ? .leading : .trailing)
        .padding(.horizontal, 4)
    }
}


Solution 1:[1]

for the first error you should use that code instead of your code where you make a background with RoundRectangle the same to your base rectangle and make the fill of that the color you want which is green

              RoundedRectangle(cornerRadius: 25, style: .continuous)
                    .stroke(Color.brown, lineWidth: 1).background(RoundedRectangle(cornerRadius: 25).fill(Color.green))
                     .frame(width: 300, alignment: Alignment.top )
                     .padding([.bottom], 5)
                     .clipped()

the second issue in your ContentView you should init your UITextView background color to clear and after that make your textEditor Color clear using that code

    init() {
       UITextView.appearance().backgroundColor = .clear
   }

and make your textEditor background clear

TextEditor (text: $textTyped)
                .frame(height: 200, alignment: .leading)
                .padding(.horizontal, 10)
                .background(Color.clear)

and the third issue is that i think you are using the array count but you should use the id of each message so when if we suppose that the last message-id is 728398 in your onChange

onChange(of: messageArrayObservedObject.messagesDBArray.count) { id in
                // When the lastMessageId changes, scroll to the bottom of the conversation
                withAnimation {
                    print("ididididid\(id)")
                    proxy.scrollTo(messageArrayObservedObject.messagesDBArray.last, anchor: .bottom)
                }
            }

your are using the ( messageArrayObservedObject.messagesDBArray.count )counts of messages like 5 message so you are scrolling to 5 not to the id of message which is 728398

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1