简体   繁体   English

在 SwiftUI (UIViewRepresentable) 中向 UITextView 添加占位符

[英]Adding placeholder to UITextView in SwiftUI (UIViewRepresentable)

I am trying to add a placeholder to my textViews made with SwiftUI, but when doing textView.text = placeholder or textView.text = "" , nothing happens...我正在尝试在使用 SwiftUI 制作的 textViews 中添加一个占位符,但是在执行textView.text = placeholdertextView.text = ""时,什么也没有发生

Using textView.insertText(placeholder) works, but then I am unsure on how to remove the placeholder upon typing into the textView ( textView.deleteBackward() for every letter in placeholder maybe)使用textView.insertText(placeholder)有效,但是我不确定如何在输入 textView 时删除占位符( textView.deleteBackward()中的每个字母可能)

Here is my TextView.swift code:这是我的 TextView.swift 代码:

import Foundation
import SwiftUI
 
struct TextView: UIViewRepresentable {
    
    @Binding var text: String
    var placeholder: String
    let textStyle: UIFont.TextStyle
    @Binding var isFirstResponder: Bool
    
    let keyboard: String
 
    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        
        textView.delegate = context.coordinator
        textView.isSelectable = true
        textView.isUserInteractionEnabled = true
        textView.font = UIFont.preferredFont(forTextStyle: textStyle)
        textView.textAlignment = .center
        textView.autocapitalizationType = .none
        textView.autocorrectionType = .no
        textView.inputAssistantItem.leadingBarButtonGroups = []
        textView.inputAssistantItem.trailingBarButtonGroups = []
        if keyboard == "dummy" {
            let dummyBoard = NumKeyboard(frame: CGRect(x: 500, y: 500, width: 0, height: 0), textView: textView)
            textView.inputView = dummyBoard
        } else if keyboard == "num" {
            let keyboardView = NumKeyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 300), textView: textView)
            textView.inputView = keyboardView
            keyboardView.delegate = context.coordinator
        } else if keyboard == "alphaNum" {
            let keyboardView = AlphaNumKeyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 300),type: "UNIX", textView: textView)
            textView.inputView = keyboardView
            keyboardView.delegate = context.coordinator
        }


        textView.text = placeholder
        textView.textColor = UIColor.lightGray
        
        return textView
    }
 
    func updateUIView(_ uiView: UITextView, context: Context) {
        if uiView.text != text {
            uiView.text = text
        }
       
        DispatchQueue.main.async {
            if self.isFirstResponder && !uiView.isFirstResponder {
                uiView.becomeFirstResponder()
            }
            if !self.isFirstResponder && uiView.isFirstResponder {
                uiView.resignFirstResponder()
            }
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator($text, $isFirstResponder, placeholder)
    }
     
    class Coordinator: NSObject, UITextViewDelegate, KeyboardDelegate {
        @Binding var text: String
        @Binding var isFirstResponder: Bool
        var placeholder: String
     
        init(_ text: Binding<String>, _ isFirstResponder: Binding<Bool>, _ placeholder: String) {
            _text = text
            _isFirstResponder = isFirstResponder
            self.placeholder = placeholder
        }
     
        func textViewDidChange(_ textView: UITextView) {
            self.text = textView.text
        }
        
        
        func textViewDidBeginEditing(_ textView: UITextView) {

            if textView.textColor == UIColor.lightGray {
                print(placeholder)
                textView.text = nil
                textView.textColor = UIColor.black
            }
        }

        func textViewDidEndEditing(_ textView: UITextView) {

            if textView.text.isEmpty {
                textView.text = placeholder
                textView.textColor = UIColor.lightGray
            } else {
                self.text = textView.text
            }
        }
    }
}

UITextView doesn't inherently have a placeholder property so you'd have to create and manipulate one programmatically using your own methods. UITextView本身没有占位符属性,因此您必须使用自己的方法以编程方式创建和操作一个。 I recommend using either this solution below and it depends on the desired behavior.我建议使用以下任一解决方案,这取决于所需的行为。

Solution: So an approach to do this, is I made the color gray to the text and I made it as default.解决方案:所以一种方法是,我将文本设置为gray ,并将其设置为默认值。 Then I have created a variable didStartEditing to check, if the user click on the textView , the placeholder will be removed.然后我创建了一个变量didStartEditing来检查,如果用户点击textView ,占位符将被删除。

So here it is an example that I just did, you can take it and change it to suit your needs:所以这是我刚刚做的一个例子,你可以把它改成适合你的需要:

First this is the TextView struct.首先这是TextView结构。

struct TextView: UIViewRepresentable {

@Binding var text: String
@Binding var didStartEditing: Bool


func makeUIView(context: Context) -> UITextView {
    let textView = UITextView()
    
    textView.font = UIFont.preferredFont(forTextStyle: .body)
    textView.autocapitalizationType = .sentences
    textView.isSelectable = true
    textView.isUserInteractionEnabled = true
    
    return textView
}


func updateUIView(_ uiView: UITextView, context: Context) {
    
    if didStartEditing {
        
        uiView.textColor = UIColor.black
        uiView.text = text
        
    }
    else {
        uiView.text = "This is a place holder"
        uiView.textColor = UIColor.lightGray
    }
    
    uiView.font = UIFont.preferredFont(forTextStyle: .body)
    
}
} 

And then this is the SwiftUI code:然后这是 SwiftUI 代码:

@State var text = ""
@State var didStartEditing = false

var body: some View {
    TextView(text: $text, didStartEditing: $didStartEditing)
        .onTapGesture {
            didStartEditing = true
        }
}

The result as you requested:您要求的结果:

结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM