Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add placeholder text to TextEditor in SwiftUI?

When using SwiftUI's new TextEditor, you can modify its content directly using a @State. However, I haven't see a way to add a placeholder text to it. Is it doable right now?

enter image description here

I added an example that Apple used in their own translator app. Which appears to be a multiple lines text editor view that supports a placeholder text.

like image 421
Legolas Wang Avatar asked Jul 05 '20 14:07

Legolas Wang


People also ask

How do you add a placeholder in text view?

Solution #1 - If you want the placeholder to disappear as soon as the user selects the text view: First set the UITextView to contain the placeholder text and set it to a light gray color to mimic the look of a UITextField 's placeholder text. Either do so in the viewDidLoad or upon the text view's creation.

How do I change TextEditor background in SwiftUI?

TextEditor is backed by UITextView . So you need to get rid of the UITextView 's backgroundColor first and then you can set any View to the background .

Is placeholder a SwiftUI?

SwiftUI lets us mark text as a placeholder in our view, meaning that it gets rendered but masked out with gray to show it isn't final content. This is provided through the redacted(reason:) modifier, along with an unredacted() modifier you can use to override redaction as needed.

Is there a multiple line text editor view for SwiftUI?

Which seems like a multiple lines text editor view that supports a placeholder text. This solution is adapted from responses (primarily Mojtaba Hosseini) to a couple of similar questions on StackOverflow and also from Alan Quatermain's well written blog titled "SwiftUI Bindings with CoreData".

How do I add placeholder text to a UITextView?

First set the UITextView to contain the placeholder text and set it to a light gray color to mimic the look of a UITextField 's placeholder text. Either do so in the viewDidLoad or upon the text view's creation. textView.text = "Placeholder" textView.textColor = UIColor.lightGray

Is there a text editor view that supports placeholder text?

One example is the text input in Apple's own translator app. Which seems like a multiple lines text editor view that supports a placeholder text.

How do I hide the placeholder text in a text view?

Solution #1 - If you want the placeholder to disappear as soon as the user selects the text view: First set the UITextView to contain the placeholder text and set it to a light gray color to mimic the look of a UITextField 's placeholder text. Either do so in the viewDidLoad or upon the text view's creation.


2 Answers

It is not possible out of the box but you can achieve this effect with ZStack or the .overlay property.

What you should do is check the property holding your state. If it is empty display your placeholder text. If it's not then display the inputted text instead.

And here is a code example:

ZStack(alignment: .leading) {
    if email.isEmpty {
        Text(Translation.email)
            .font(.custom("Helvetica", size: 24))
            .padding(.all)
    }
    
    TextEditor(text: $email)
        .font(.custom("Helvetica", size: 24))
        .padding(.all)
}

Note: I have purposely left the .font and .padding styling for you to see that it should match on both the TextEditor and the Text.

EDIT: Having in mind the two problems mentioned in Legolas Wang's comment here is how the alignment and opacity issues could be handled:

  • In order to make the Text start at the left of the view simply wrap it in HStack and append Spacer immediately after it like this:
HStack {
   Text("Some placeholder text")
   Spacer()
}
  • In order to solve the opaque problem you could play with conditional opacity - the simplest way would be using the ternary operator like this:
TextEditor(text: stringProperty)        
        .opacity(stringProperty.isEmpty ? 0.25 : 1)

Of course this solution is just a silly workaround until support gets added for TextEditors.

like image 194
bde.dev Avatar answered Oct 19 '22 00:10

bde.dev


You can use a ZStack with a disabled TextEditor containing your placeholder text behind. For example:

ZStack {
    if self.content.isEmpty {
            TextEditor(text:$placeholderText)
                .font(.body)
                .foregroundColor(.gray)
                .disabled(true)
                .padding()
    }
    TextEditor(text: $content)
        .font(.body)
        .opacity(self.content.isEmpty ? 0.25 : 1)
        .padding()
}
like image 21
Magnus Avatar answered Oct 19 '22 01:10

Magnus