¿Agregar texto de marcador de posición dentro de UITextView en Swift?
¿Cómo puedo agregar un marcador de posición en un UITextView
, similar al que puedes configurar UITextField
en Swift
?
Actualizado para Swift 4
UITextView
no tiene inherentemente una propiedad de marcador de posición, por lo que tendría que crear y manipular una mediante programación utilizando UITextViewDelegate
métodos. Recomiendo usar la solución n.° 1 o n.° 2 a continuación, según el comportamiento deseado.
Nota: Para cualquiera de las soluciones, agréguelo UITextViewDelegate
a la clase y configúrelo textView.delegate = self
para usar los métodos delegados de la vista de texto.
Solución #1 : si desea que el marcador de posición desaparezca tan pronto como el usuario seleccione la vista de texto:
Primero configure el UITextView
para que contenga el texto del marcador de posición y configúrelo en un color gris claro para imitar el aspecto del UITextField
texto del marcador de posición. Hágalo en el viewDidLoad
momento de la creación de la vista de texto.
textView.text = "Placeholder"
textView.textColor = UIColor.lightGray
Luego, cuando el usuario comience a editar la vista de texto, si la vista de texto contiene un marcador de posición (es decir, si el color del texto es gris claro), borre el texto del marcador de posición y establezca el color del texto en negro para acomodar la entrada del usuario.
func textViewDidBeginEditing(_ textView: UITextView) {
if textView.textColor == UIColor.lightGray {
textView.text = nil
textView.textColor = UIColor.black
}
}
Luego, cuando el usuario termine de editar la vista de texto y renunció como primer respondedor, si la vista de texto está vacía, restablezca su marcador de posición volviendo a agregar el texto del marcador de posición y configurando su color en gris claro.
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty {
textView.text = "Placeholder"
textView.textColor = UIColor.lightGray
}
}
Solución #2 : si desea que el marcador de posición se muestre siempre que la vista de texto esté vacía, incluso si la vista de texto está seleccionada:
Primero establezca el marcador de posición en viewDidLoad
:
textView.text = "Placeholder"
textView.textColor = UIColor.lightGray
textView.becomeFirstResponder()
textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument)
(Nota: dado que el OP quería seleccionar la vista de texto tan pronto como se carga la vista, incorporé la selección de vista de texto en el código anterior. Si este no es el comportamiento deseado y no desea que se seleccione la vista de texto al cargar la vista, elimine las dos últimas líneas del fragmento de código anterior).
Luego utilice el shouldChangeTextInRange
UITextViewDelegate
método, así:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
// Combine the textView text and the replacement text to
// create the updated text string
let currentText:String = textView.text
let updatedText = (currentText as NSString).replacingCharacters(in: range, with: text)
// If updated text view will be empty, add the placeholder
// and set the cursor to the beginning of the text view
if updatedText.isEmpty {
textView.text = "Placeholder"
textView.textColor = UIColor.lightGray
textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument)
}
// Else if the text view's placeholder is showing and the
// length of the replacement string is greater than 0, set
// the text color to black then set its text to the
// replacement string
else if textView.textColor == UIColor.lightGray && !text.isEmpty {
textView.textColor = UIColor.black
textView.text = text
}
// For every other case, the text should change with the usual
// behavior...
else {
return true
}
// ...otherwise return false since the updates have already
// been made
return false
}
Y también implementar textViewDidChangeSelection
para evitar que el usuario cambie la posición del cursor mientras el marcador de posición está visible. (Nota: textViewDidChangeSelection
se llama antes de que se cargue la vista, así que solo verifique el color de la vista de texto si la ventana está visible):
func textViewDidChangeSelection(_ textView: UITextView) {
if self.view.window != nil {
if textView.textColor == UIColor.lightGray {
textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument)
}
}
}
Marcador de posición flotante
Es simple, seguro y confiable colocar una etiqueta de marcador de posición sobre una vista de texto, configurar su fuente, color y administrar la visibilidad del marcador de posición mediante el seguimiento de los cambios en el recuento de caracteres de la vista de texto.
Actualización: sugerencias incorporadas hechas por @RakshithaMurangaRodrigo en el comentario del 10 de febrero del 23
Rápido 5:
class NotesViewController : UIViewController {
@IBOutlet var textView : UITextView!
var placeholderLabel : UILabel!
override func viewDidLoad() {
super.viewDidLoad()
textView.delegate = self
placeholderLabel = UILabel()
placeholderLabel.text = "Enter some text..."
placeholderLabel.font = .italicSystemFont(ofSize: (textView.font?.pointSize)!)
placeholderLabel.sizeToFit()
textView.addSubview(placeholderLabel)
placeholderLabel.frame.origin = CGPoint(x: 5, y: (textView.font?.pointSize)! / 2)
placeholderLabel.textColor = .tertiaryLabel
placeholderLabel.isHidden = !textView.text.isEmpty
}
}
extension NotesViewController : UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
placeholderLabel?.isHidden = !textView.text.isEmpty
}
func textViewDidEndEditing(_ textView: UITextView) {
placeholderLabel?.isHidden = !textView.text.isEmpty
}
func textViewDidBeginEditing(_ textView: UITextView) {
placeholderLabel?.isHidden = true
}
}
Rápido:
Agregue su vista de texto mediante programación o mediante Interface Builder, si es el último, cree la salida:
@IBOutlet weak var yourTextView: UITextView!
Agregue el delegado (UITextViewDelegate):
class ViewController: UIViewController, UITextViewDelegate {
En el método viewDidLoad, agregue lo siguiente:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
yourTextView.delegate = self
yourTextView.text = "Placeholder text goes right here..."
yourTextView.textColor = UIColor.lightGray
Ahora déjame presentarte la parte mágica, agrega esta función:
func textViewDidBeginEditing(_ textView: UITextView) {
if yourTextView.textColor == UIColor.lightGray {
yourTextView.text = ""
yourTextView.textColor = UIColor.black
}
}
Tenga en cuenta que esto se ejecutará cada vez que comience la edición, allí verificaremos las condiciones para indicar el estado, usando la propiedad de color. Configurar el texto en nil
No lo recomiendo. Inmediatamente después de eso, configuramos el color del texto deseado, en este caso, negro.
Ahora agregue esta función también:
func textViewDidEndEditing(_ textView: UITextView) {
if yourTextView.text == "" {
yourTextView.text = "Placeholder text ..."
yourTextView.textColor = UIColor.lightGray
}
}
Let me insist, do not compare to nil
, i have already tried that and it would not work. We then set the values back to placeholder style, and set the color back to placeholder color because it is a condition to check in textViewDidBeginEditing
.