Cameron Delong
Cameron Delong

Reputation: 704

How to make TextEditor look like TextField - SwiftUI

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!

Upvotes: 3

Views: 4459

Answers (3)

Iulian Onofrei
Iulian Onofrei

Reputation: 9710

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

Upvotes: 5

Estuardo Recargador
Estuardo Recargador

Reputation: 39

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)
            )
    )
…

Upvotes: 1

jnpdx
jnpdx

Reputation: 52312

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.

Upvotes: 2

Related Questions