4

I'm looking for a way to make a swiftUI TextEditor look like a TextField. I need a multiline input but I really like the appearance of rounded TextFields.

This is the closest I was able to get: enter image description here

Using this code:

TextEditor(text: $instanceNotes)
    .border(Color.gray)
    .foregroundColor(.secondary)
    .cornerRadius(3)
    .padding(.horizontal)
    .frame(height:100)

which looks/acts nothing like a TextField

This is the code for the TextField I want to replicate:

TextField("Name", text: $instanceName)
    .textFieldStyle(RoundedBorderTextFieldStyle())
    .padding(.horizontal)

Thanks!

3 Answers 3

6

Having the TextEditor in a Form causes the default style to change, so, the accepted answer doesn't work correctly.

I managed to get it working using:

import PlaygroundSupport
import SwiftUI

struct ContentView: View {
    @State private var text: String = "Test"

    var body: some View {
        Form {
            TextEditor(text: self.$text)
                .background(Color.primary.colorInvert())
                .cornerRadius(5)
                .overlay(
                    RoundedRectangle(cornerRadius: 5)
                        .stroke(.black, lineWidth: 1 / 3)
                        .opacity(0.3)
                )
            TextField("", text: self.$text)
                .textFieldStyle(.roundedBorder)
        }
    }
}

PlaygroundPage.current.setLiveView(
    VStack {
        ContentView()
            .environment(\.colorScheme, .light)
        ContentView()
            .environment(\.colorScheme, .dark)
    }
)

screenshot

Sign up to request clarification or add additional context in comments.

1 Comment

I found using custom colors don't really work, but if you use .black stroke with .opacity(0.2) it gets you close to the standard .textFieldStyle(.roundedBorder) border colors.
2

This gets closer (no focus support, although that could be added):

TextEditor(text: $textBinding)
    .padding(4)
    .overlay(RoundedRectangle(cornerRadius: 8)
        .stroke(Color.secondary).opacity(0.5))

I think the most important thing is making sure that the border is actually rounded -- right now, yours is getting cut off at the corners.

2 Comments

That looks much better, thanks! It still doesn't look quite like the textField, with the slight different in line width on the bottom and top that TextField has, but it's much better than what I came up with. How could I change it when it's focused like TextField does?
Probably depends on your min OS target. See: swiftui-lab.com/working-with-focus-on-swiftui-views
1

How could I change it when it's focused like TextField does?

…
@State private var text: String = ""
@FocusState private var isFocused: Bool
…
…
TextEditor(text: $textBinding)
    .focused($isFocused)
    .padding(4)
    .overlay(RoundedRectangle(cornerRadius: 8)
        .stroke(isFocused ? Color.secondary : Color.clear).opacity(0.5))
…

Show a TextEditor more accurately like a TextField:

…
Text(text)
    .padding(.vertical, 10)                         //  If not text first line hides under TextField
    .padding(.horizontal, 5)                        //  If not TextField can be saw on the right side
    .frame(maxWidth: .infinity,                     //  Frame on the screen size
           minHeight: 40                            //  Initial size equivalent to one line
    )
    .overlay(
        TextEditor(text: $text)
            .focused($isFocused)
            .overlay(
                RoundedRectangle(cornerRadius: 8)
                    .stroke(isFocused ? Color.secondary : Color.clear).opacity(0.5)
            )
    )
…

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.