admin管理员组

文章数量:1421028

I'm currently trying to replicate the text entry that Slack has on its macOS client. It's a mix between the text entry on Apple Messages and other texting apps.

I landed on the use of a TextEditor instead of a TextField because it allows me more easily to have multilines with returns in it. Following various articles here at Stack Overflow and others (particularly this one and this one) I landed on the following code.

@State private var textEditorHeight : CGFloat = 100
private var maxHeight : CGFloat = 250

   HStack {    
    ZStack(alignment: .leading) {
        Text(newNoteText)
            .font(.system(.body))
            .foregroundColor(.clear)
            .padding(10)
            .background(GeometryReader {
                Color.clear.preference(key: ViewHeightKey.self,
                                       value: $0.frame(in: .local).size.height)
            })
        
        TextEditor(text: $newNoteText)
            .font(.system(.body))
            .frame(height: min(textEditorHeight, maxHeight))
            //.background(Color(NSColor.controlBackgroundColor))
            .overlay(RoundedRectangle(cornerRadius: 5).stroke(.secondary))
            .padding(.top, 5)
            .padding(.leading, 5)
            .padding(.bottom, 5)
    }
    .background(Color(NSColor.controlBackgroundColor)).edgesIgnoringSafeArea(.all)
    
    Button("Add") {
        guard !newNoteText.isEmpty else { return }
        viewModel.addNote(text: newNoteText)
        newNoteText = ""
    }
    .padding(.trailing, 10)
}
.onPreferenceChange(ViewHeightKey.self) { textEditorHeight = $0 }
.background(Color(NSColor.controlBackgroundColor)).ignoresSafeArea().edgesIgnoringSafeArea(.all)



struct ViewHeightKey: PreferenceKey {
    static var defaultValue: CGFloat { 0 }
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value = value + nextValue()
    }
}

This mostly works but the HStack adds an area around the button and the TextEditor that is gray, and not white (in light mode). Like this:

I was able to remove some of it by adding .background(Color(NSColor.controlBackgroundColor)).edgesIgnoringSafeArea(.all) and different padding options, but there is the line left on top:

Searching for a solution I found "SwiftUI - How do I change the background color of a View?"

And I've tried all the proposed solutions. I've also tried with different padding() options and overlays, but nothing seems to work so far.

So, how can I either get rid of that, or change its color to match that of the TextEditor?

Thank you!

I'm currently trying to replicate the text entry that Slack has on its macOS client. It's a mix between the text entry on Apple Messages and other texting apps.

I landed on the use of a TextEditor instead of a TextField because it allows me more easily to have multilines with returns in it. Following various articles here at Stack Overflow and others (particularly this one and this one) I landed on the following code.

@State private var textEditorHeight : CGFloat = 100
private var maxHeight : CGFloat = 250

   HStack {    
    ZStack(alignment: .leading) {
        Text(newNoteText)
            .font(.system(.body))
            .foregroundColor(.clear)
            .padding(10)
            .background(GeometryReader {
                Color.clear.preference(key: ViewHeightKey.self,
                                       value: $0.frame(in: .local).size.height)
            })
        
        TextEditor(text: $newNoteText)
            .font(.system(.body))
            .frame(height: min(textEditorHeight, maxHeight))
            //.background(Color(NSColor.controlBackgroundColor))
            .overlay(RoundedRectangle(cornerRadius: 5).stroke(.secondary))
            .padding(.top, 5)
            .padding(.leading, 5)
            .padding(.bottom, 5)
    }
    .background(Color(NSColor.controlBackgroundColor)).edgesIgnoringSafeArea(.all)
    
    Button("Add") {
        guard !newNoteText.isEmpty else { return }
        viewModel.addNote(text: newNoteText)
        newNoteText = ""
    }
    .padding(.trailing, 10)
}
.onPreferenceChange(ViewHeightKey.self) { textEditorHeight = $0 }
.background(Color(NSColor.controlBackgroundColor)).ignoresSafeArea().edgesIgnoringSafeArea(.all)



struct ViewHeightKey: PreferenceKey {
    static var defaultValue: CGFloat { 0 }
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value = value + nextValue()
    }
}

This mostly works but the HStack adds an area around the button and the TextEditor that is gray, and not white (in light mode). Like this:

I was able to remove some of it by adding .background(Color(NSColor.controlBackgroundColor)).edgesIgnoringSafeArea(.all) and different padding options, but there is the line left on top:

Searching for a solution I found "SwiftUI - How do I change the background color of a View?"

And I've tried all the proposed solutions. I've also tried with different padding() options and overlays, but nothing seems to work so far.

So, how can I either get rid of that, or change its color to match that of the TextEditor?

Thank you!

Share Improve this question asked Mar 15 at 19:42 AlephAleph 5934 silver badges20 bronze badges 8
  • You could try replacing your .background(Color(NSColor.controlBackgroundColor)) with .background(Color.clear). – workingdog support Ukraine Commented Mar 16 at 0:44
  • Thank you @workingdogsupportUkraine, I have already tried and it doesn't appear to show any difference. – Aleph Commented Mar 16 at 10:05
  • I'm surprised it does not work for you. It works well for me, on macOS 15.4, using Xcode 16.3. – workingdog support Ukraine Commented Mar 16 at 10:21
  • Same. But it's still showing that gray line... – Aleph Commented Mar 16 at 11:21
  • Added my test code. Let me know if this code does not work for you. – workingdog support Ukraine Commented Mar 16 at 13:03
 |  Show 3 more comments

1 Answer 1

Reset to default 1

Here is my test code that works for me. This example code should hide the HStack gray area around the button and the TextEditor. The areas will take the background color.


struct ContentView: View {
    var body: some View {
        ZStack(alignment: .leading) {
            // for testing, try green
            Color.white.ignoresSafeArea(edges: .all)
            TestView()
        }
    }
}

struct TestView: View {
    @State private var newNoteText = ""
    @State private var textEditorHeight: CGFloat = 100
    
    let maxHeight: CGFloat = 250
    
    var body: some View {
        HStack {
            ZStack(alignment: .leading) {
                Text(newNoteText)
                    .font(.system(.body))
                    .foregroundColor(.clear)
                    .padding(10)
                    .background(GeometryReader {
                        Color.clear.preference(key: ViewHeightKey.self,
                                               value: $0.frame(in: .local).size.height)
                    })
                
                TextEditor(text: $newNoteText)
                    .font(.system(.body))
                    .frame(height: min(textEditorHeight, maxHeight))
                    .overlay(RoundedRectangle(cornerRadius: 5).stroke(.secondary))
                    .padding(.top, 5)
                    .padding(.leading, 5)
                    .padding(.bottom, 5)
            }
        //  .background(Color.clear) // <--- here, if needed

            Button("Add") {
                guard !newNoteText.isEmpty else { return }
                // viewModel.addNote(text: newNoteText)
                newNoteText = ""
            }
            .padding(.trailing, 10)
        }
        .onPreferenceChange(ViewHeightKey.self) { textEditorHeight = $0 }
        .background(Color.clear) // <--- here, HStack color
        .edgesIgnoringSafeArea(.all)
    }
}

struct ViewHeightKey: PreferenceKey {
    static var defaultValue: CGFloat { 0 }
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value = value + nextValue()
    }
}

本文标签: macosRemoving or changing the the color of HStackStack Overflow