文本视图占位符Swift

我正在做一个使用文本视图的应用程序。 现在我希望文本视图具有与您可以为文本字段设置的占位符类似的占位符。 你将如何使用swift来完成这个任务。

有谁知道如何做到这一点?

更新了Swift 3

UITextView本身并不具有占位符属性,因此您必须使用UITextViewDelegate方法以编程方式创build和操作一个占位符属性。

(注意:将UITextViewDelegate添加到该类并设置textView.delegate = self 。)

首先设置UITextView以包含占位符文本,并将其设置为浅灰色以模仿UITextField占位符文本的外观。 要么在viewDidLoad要么在文本视图的创build。

 textView.text = "Placeholder" textView.textColor = UIColor.lightGray 

然后,当用户开始编辑文本视图时,如果文本视图包含占位符(即其文本颜色为浅灰色),请清除占位符文本,并将文本颜色设置为黑色以适应用户的input。

 func textViewDidBeginEditing(_ textView: UITextView) { if textView.textColor == UIColor.lightGray { textView.text = nil textView.textColor = UIColor.black } } 

然后,当用户完成文本视图的编辑并将其作为第一响应者辞职时,如果文本视图为空,则通过重新添加占位符文本并将其颜色设置为浅灰色来重置其占位符。

 func textViewDidEndEditing(_ textView: UITextView) { if textView.text.isEmpty { textView.text = "Placeholder" textView.textColor = UIColor.lightGray } } 

更新:正如在评论中所讨论的,OP希望在加载视图时popup键盘,然后保持整个时间,所以他希望文本视图占位符在文本字段为空时显示,即使键盘仍然显示。

为此,首先在viewDidLoad设置占位符:

 textView.text = "Placeholder" textView.textColor = UIColor.lightGray textView.becomeFirstResponder() textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument) 

然后使用shouldChangeTextInRange UITextViewDelegate方法,如下所示:

 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 = textView.text let updatedText = currentText?.replacingCharacters(in: range as 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) return false } // Else if the text view's placeholder is showing and the // length of the replacement string is greater than 0, clear // the text view and set its color to black to prepare for // the user's entry else if textView.textColor == UIColor.lightGray && !text.isEmpty { textView.text = nil textView.textColor = UIColor.black } return true } 

而且还实现了textViewDidChangeSelection以防止用户在占位符可见的时候改变游标的位置。 (注意:在加载视图之前调用textViewDidChangeSelection所以如果窗口可见,只检查文本视图的颜色):

 func textViewDidChangeSelection(_ textView: UITextView) { if self.view.window != nil { if textView.textColor == UIColor.lightGray { textView.selectedTextRange = textView.textRange(from: textView.beginningOfDocument, to: textView.beginningOfDocument) } } } 

浮动占位符


在文本视图上方放置占位符标签很简单,安全可靠,通过跟踪对文本视图字符数的更改来设置字体,颜色和pipe理占位符可见性。

Swift 3:

 class NotesViewController : UIViewController, UITextViewDelegate { @IBOutlet var textView : UITextView! var placeholderLabel : UILabel! override func viewDidLoad() { super.viewDidLoad() textView.delegate = self placeholderLabel = UILabel() placeholderLabel.text = "Enter some text..." placeholderLabel.font = UIFont.italicSystemFont(ofSize: (textView.font?.pointSize)!) placeholderLabel.sizeToFit() textView.addSubview(placeholderLabel) placeholderLabel.frame.origin = CGPoint(x: 5, y: (textView.font?.pointSize)! / 2) placeholderLabel.textColor = UIColor.lightGray placeholderLabel.isHidden = !textView.text.isEmpty } func textViewDidChange(_ textView: UITextView) { placeholderLabel.isHidden = !textView.text.isEmpty } } 

Swift 2:相同,除了: italicSystemFontOfSize(textView.font.pointSize) UIColor.lightGrayColor italicSystemFontOfSize(textView.font.pointSize)UIColor.lightGrayColor


强烈build议使用KMPlaceholderTextView库。 使用非常简单。

迅速:

以编程方式或通过Interface Builder添加文本视图,如果最后一个,创build出口:

 @IBOutlet weak var yourTextView: UITextView! 

请添加委托(UITextViewDelegate):

 class ViewController: UIViewController, UITextViewDelegate { 

在viewDidLoad方法中,添加以下内容:

 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 

现在让我来介绍一下魔术部分,添加这个function:

 func textViewDidBeginEditing(_ textView: UITextView) { if yourTextView.textColor == UIColor.lightGray { yourTextView.text = "" yourTextView.textColor = UIColor.black } } 

请注意,这将执行每当编辑开始,我们将检查条件告诉状态,使用颜色属性。 设置文字nil我不build议。 之后,我们将文本颜色设置为所需,在这种情况下,黑色。

现在也添加这个function:

 func textViewDidEndEditing(_ textView: UITextView) { if yourTextView.text == "" { yourTextView.text = "Placeholder text ..." yourTextView.textColor = UIColor.lightGray } } 

让我坚持,不要与nil比较,我已经试过了,这是行不通的。 然后,我们将值设置回占位符样式,并将颜色设置为占位符颜色,因为这是检查textViewDidBeginEditing一个条件。

我通过使用两个不同的文本视图做到这一点:

  1. 一个在用作占位符的背景中。
  2. 一个在用户实际input的前台(具有透明背景)

这个想法是,一旦用户开始在前台视图中input东西,背景中的占位符消失(如果用户删除所有内容,则会重新出现)。 所以它的行为与单行文本字段的占位符完全相同。

这是我用它的代码。 请注意,descriptionField是用户键入的字段,而descriptionPlaceholder是后台中的字段。

 func textViewDidChange(descriptionField: UITextView) { if descriptionField.text.isEmpty == false { descriptionPlaceholder.text = "" } else { descriptionPlaceholder.text = descriptionPlaceholderText } } 

SET值在视图加载

  txtVw!.autocorrectionType = UITextAutocorrectionType.No txtVw!.text = "Write your Placeholder" txtVw!.textColor = UIColor.lightGrayColor() func textViewDidBeginEditing(textView: UITextView) { if (txtVw?.text == "Write your Placeholder") { txtVw!.text = nil txtVw!.textColor = UIColor.blackColor() } } func textViewDidEndEditing(textView: UITextView) { if txtVw!.text.isEmpty { txtVw!.text = "Write your Placeholder" txtVw!.textColor = UIColor.lightGrayColor() } textView.resignFirstResponder() } 

我不知道为什么这么多人把这个问题搞得这么复杂……这是相当直接和简单的。 这是UITextView的一个子类,它提供了所需的function。

 - (void)customInit { self.contentMode = UIViewContentModeRedraw; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil]; } - (void)textChanged:(NSNotification *)notification { if (notification.object == self) { if(self.textStorage.length != 0 || !self.textStorage.length) { [self setNeedsDisplay]; } } } #pragma mark - Setters - (void)setPlaceholderText:(NSString *)placeholderText withFont:(UIFont *)font { self.placeholderText = placeholderText; self.placeholderTextFont = font; } - (void)drawRect:(CGRect)rect { [super drawRect:rect]; [[UIColor lightGrayColor] setFill]; if (self.textStorage.length != 0) { return; } CGRect inset = CGRectInset(rect, 8, 8);//Default rect insets for textView NSDictionary *attributes = @{NSFontAttributeName: self.placeholderTextFont, NSForegroundColorAttributeName: [UIColor grayColor]}; [self.placeholderText drawInRect:inset withAttributes:attributes]; }` 

我试图使clearlight的答案方便的代码。

 extension UITextView{ func setPlaceholder() { let placeholderLabel = UILabel() placeholderLabel.text = "Enter some text..." placeholderLabel.font = UIFont.italicSystemFont(ofSize: (self.font?.pointSize)!) placeholderLabel.sizeToFit() placeholderLabel.tag = 222 placeholderLabel.frame.origin = CGPoint(x: 5, y: (self.font?.pointSize)! / 2) placeholderLabel.textColor = UIColor.lightGray placeholderLabel.isHidden = !self.text.isEmpty self.addSubview(placeholderLabel) } func checkPlaceholder() { let placeholderLabel = self.viewWithTag(222) as! UILabel placeholderLabel.isHidden = !self.text.isEmpty } } 

用法

 override func viewDidLoad() { textView.delegate = self textView.setPlaceholder() } func textViewDidChange(_ textView: UITextView) { textView.checkPlaceholder() } 

另外一个解决scheme(Swift 3):

 import UIKit protocol PlaceholderTextViewDelegate { func placeholderTextViewDidChangeText(_ text:String) func placeholderTextViewDidEndEditing(_ text:String) } final class PlaceholderTextView: UITextView { var notifier:PlaceholderTextViewDelegate? var placeholder: String? { didSet { placeholderLabel?.text = placeholder } } var placeholderColor = UIColor.lightGray var placeholderFont = UIFont.appMainFontForSize(14.0) { didSet { placeholderLabel?.font = placeholderFont } } fileprivate var placeholderLabel: UILabel? // MARK: - LifeCycle init() { super.init(frame: CGRect.zero, textContainer: nil) awakeFromNib() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override func awakeFromNib() { super.awakeFromNib() self.delegate = self NotificationCenter.default.addObserver(self, selector: #selector(PlaceholderTextView.textDidChangeHandler(notification:)), name: .UITextViewTextDidChange, object: nil) placeholderLabel = UILabel() placeholderLabel?.textColor = placeholderColor placeholderLabel?.text = placeholder placeholderLabel?.textAlignment = .left placeholderLabel?.numberOfLines = 0 } override func layoutSubviews() { super.layoutSubviews() placeholderLabel?.font = placeholderFont var height:CGFloat = placeholderFont.lineHeight if let data = placeholderLabel?.text { let expectedDefaultWidth:CGFloat = bounds.size.width let fontSize:CGFloat = placeholderFont.pointSize let textView = UITextView() textView.text = data textView.font = UIFont.appMainFontForSize(fontSize) let sizeForTextView = textView.sizeThatFits(CGSize(width: expectedDefaultWidth, height: CGFloat.greatestFiniteMagnitude)) let expectedTextViewHeight = sizeForTextView.height if expectedTextViewHeight > height { height = expectedTextViewHeight } } placeholderLabel?.frame = CGRect(x: 5, y: 0, width: bounds.size.width - 16, height: height) if text.isEmpty { addSubview(placeholderLabel!) bringSubview(toFront: placeholderLabel!) } else { placeholderLabel?.removeFromSuperview() } } func textDidChangeHandler(notification: Notification) { layoutSubviews() } } extension PlaceholderTextView : UITextViewDelegate { // MARK: - UITextViewDelegate func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if(text == "\n") { textView.resignFirstResponder() return false } return true } func textViewDidChange(_ textView: UITextView) { notifier?.placeholderTextViewDidChangeText(textView.text) } func textViewDidEndEditing(_ textView: UITextView) { notifier?.placeholderTextViewDidEndEditing(textView.text) } } 

结果

在这里输入图像描述

使用此扩展这是在UITextView中设置占位符的最佳方法。 但请确保您已将代表附加到TextView。 您可以像这样设置占位符: –

 yourTextView.placeholder = "Placeholder" extension UITextView :UITextViewDelegate { /// Resize the placeholder when the UITextView bounds change override open var bounds: CGRect { didSet { self.resizePlaceholder() } } /// The UITextView placeholder text public var placeholder: String? { get { var placeholderText: String? if let placeholderLabel = self.viewWithTag(100) as? UILabel { placeholderText = placeholderLabel.text } return placeholderText } set { if let placeholderLabel = self.viewWithTag(100) as! UILabel? { placeholderLabel.text = newValue placeholderLabel.sizeToFit() } else { self.addPlaceholder(newValue!) } } } /// When the UITextView did change, show or hide the label based on if the UITextView is empty or not /// /// - Parameter textView: The UITextView that got updated public func textViewDidChange(_ textView: UITextView) { if let placeholderLabel = self.viewWithTag(100) as? UILabel { placeholderLabel.isHidden = self.text.characters.count > 0 } } /// Resize the placeholder UILabel to make sure it's in the same position as the UITextView text private func resizePlaceholder() { if let placeholderLabel = self.viewWithTag(100) as! UILabel? { let labelX = self.textContainer.lineFragmentPadding let labelY = self.textContainerInset.top - 2 let labelWidth = self.frame.width - (labelX * 2) let labelHeight = placeholderLabel.frame.height placeholderLabel.frame = CGRect(x: labelX, y: labelY, width: labelWidth, height: labelHeight) } } /// Adds a placeholder UILabel to this UITextView private func addPlaceholder(_ placeholderText: String) { let placeholderLabel = UILabel() placeholderLabel.text = placeholderText placeholderLabel.sizeToFit() placeholderLabel.font = self.font placeholderLabel.textColor = UIColor.lightGray placeholderLabel.tag = 100 placeholderLabel.isHidden = self.text.characters.count > 0 self.addSubview(placeholderLabel) self.resizePlaceholder() self.delegate = self } } 

在ios中没有这样的属性来直接在TextView中添加占位符,而您可以在textView中添加标签并显示/隐藏更改。 SWIFT 2.0并确保实现textviewdelegate

 func textViewDidChange(TextView: UITextView) { if txtShortDescription.text == "" { self.lblShortDescription.hidden = false } else { self.lblShortDescription.hidden = true } } 

Swift – 我写了一个inheritanceUITextView的类,我添加了一个UILabel作为子视图来充当占位符。

  import UIKit @IBDesignable class HintedTextView: UITextView { @IBInspectable var hintText: String = "hintText" { didSet{ hintLabel.text = hintText } } private lazy var hintLabel: UILabel = { let label = UILabel() label.font = UIFont.systemFontOfSize(16) label.textColor = UIColor.lightGrayColor() label.translatesAutoresizingMaskIntoConstraints = false return label }() override init(frame: CGRect, textContainer: NSTextContainer?) { super.init(frame: frame, textContainer: textContainer) setupView() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setupView() } override func prepareForInterfaceBuilder() { super.prepareForInterfaceBuilder() setupView() } private func setupView() { translatesAutoresizingMaskIntoConstraints = false delegate = self font = UIFont.systemFontOfSize(16) addSubview(hintLabel) NSLayoutConstraint.activateConstraints([ hintLabel.leftAnchor.constraintEqualToAnchor(leftAnchor, constant: 4), hintLabel.rightAnchor.constraintEqualToAnchor(rightAnchor, constant: 8), hintLabel.topAnchor.constraintEqualToAnchor(topAnchor, constant: 4), hintLabel.heightAnchor.constraintEqualToConstant(30) ]) } override func layoutSubviews() { super.layoutSubviews() setupView() } } 

我喜欢@ nerdist的解决scheme。 基于此,我创build了一个UITextView的扩展:

 import Foundation import UIKit extension UITextView { private func add(_ placeholder: UILabel) { for view in self.subviews { if let lbl = view as? UILabel { if lbl.text == placeholder.text { lbl.removeFromSuperview() } } } self.addSubview(placeholder) } func addPlaceholder(_ placeholder: UILabel?) { if let ph = placeholder { ph.numberOfLines = 0 // support for multiple lines ph.font = UIFont.italicSystemFont(ofSize: (self.font?.pointSize)!) ph.sizeToFit() self.add(ph) ph.frame.origin = CGPoint(x: 5, y: (self.font?.pointSize)! / 2) ph.textColor = UIColor(white: 0, alpha: 0.3) updateVisibility(ph) } } func updateVisibility(_ placeHolder: UILabel?) { if let ph = placeHolder { ph.isHidden = !self.text.isEmpty } } } 

例如,在ViewController类中,我是这样使用它的:

 class MyViewController: UIViewController, UITextViewDelegate { private var notePlaceholder: UILabel! @IBOutlet weak var txtNote: UITextView! ... // UIViewController override func viewDidLoad() { notePlaceholder = UILabel() notePlaceholder.text = "title\nsubtitle\nmore..." txtNote.addPlaceholder(notePlaceholder) ... } // UITextViewDelegate func textViewDidChange(_ textView: UITextView) { txtNote.updateVisbility(notePlaceholder) ... } 

占位符在UITextview!

在这里输入图像描述

更新

如果您更改代码中的textview文本,请记得调用updateVisibitly方法来隐藏占位符:

 txtNote.text = "something in code" txtNote.updateVisibility(self.notePlaceholder) // hide placeholder if text is not empty. 

为了防止占位符被多次添加,在extension add()了一个私有的add()函数。

在swift2.2中:

 public class CustomTextView: UITextView { private struct Constants { static let defaultiOSPlaceholderColor = UIColor(red: 0.0, green: 0.0, blue: 0.0980392, alpha: 0.22) } private let placeholderLabel: UILabel = UILabel() private var placeholderLabelConstraints = [NSLayoutConstraint]() @IBInspectable public var placeholder: String = "" { didSet { placeholderLabel.text = placeholder } } @IBInspectable public var placeholderColor: UIColor = CustomTextView.Constants.defaultiOSPlaceholderColor { didSet { placeholderLabel.textColor = placeholderColor } } override public var font: UIFont! { didSet { placeholderLabel.font = font } } override public var textAlignment: NSTextAlignment { didSet { placeholderLabel.textAlignment = textAlignment } } override public var text: String! { didSet { textDidChange() } } override public var attributedText: NSAttributedString! { didSet { textDidChange() } } override public var textContainerInset: UIEdgeInsets { didSet { updateConstraintsForPlaceholderLabel() } } override public init(frame: CGRect, textContainer: NSTextContainer?) { super.init(frame: frame, textContainer: textContainer) commonInit() } required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } private func commonInit() { NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(textDidChange), name: UITextViewTextDidChangeNotification, object: nil) placeholderLabel.font = font placeholderLabel.textColor = placeholderColor placeholderLabel.textAlignment = textAlignment placeholderLabel.text = placeholder placeholderLabel.numberOfLines = 0 placeholderLabel.backgroundColor = UIColor.clearColor() placeholderLabel.translatesAutoresizingMaskIntoConstraints = false addSubview(placeholderLabel) updateConstraintsForPlaceholderLabel() } private func updateConstraintsForPlaceholderLabel() { var newConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-(\(textContainerInset.left + textContainer.lineFragmentPadding))-[placeholder]", options: [], metrics: nil, views: ["placeholder": placeholderLabel]) newConstraints += NSLayoutConstraint.constraintsWithVisualFormat("V:|-(\(textContainerInset.top))-[placeholder]", options: [], metrics: nil, views: ["placeholder": placeholderLabel]) newConstraints.append(NSLayoutConstraint( item: placeholderLabel, attribute: .Width, relatedBy: .Equal, toItem: self, attribute: .Width, multiplier: 1.0, constant: -(textContainerInset.left + textContainerInset.right + textContainer.lineFragmentPadding * 2.0) )) removeConstraints(placeholderLabelConstraints) addConstraints(newConstraints) placeholderLabelConstraints = newConstraints } @objc private func textDidChange() { placeholderLabel.hidden = !text.isEmpty } public override func layoutSubviews() { super.layoutSubviews() placeholderLabel.preferredMaxLayoutWidth = textContainer.size.width - textContainer.lineFragmentPadding * 2.0 } deinit { NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextViewTextDidChangeNotification, object: nil) } 

}

在swift3:

 import UIKit 

类CustomTextView:UITextView {

 private struct Constants { static let defaultiOSPlaceholderColor = UIColor(red: 0.0, green: 0.0, blue: 0.0980392, alpha: 0.22) } private let placeholderLabel: UILabel = UILabel() private var placeholderLabelConstraints = [NSLayoutConstraint]() @IBInspectable public var placeholder: String = "" { didSet { placeholderLabel.text = placeholder } } @IBInspectable public var placeholderColor: UIColor = CustomTextView.Constants.defaultiOSPlaceholderColor { didSet { placeholderLabel.textColor = placeholderColor } } override public var font: UIFont! { didSet { placeholderLabel.font = font } } override public var textAlignment: NSTextAlignment { didSet { placeholderLabel.textAlignment = textAlignment } } override public var text: String! { didSet { textDidChange() } } override public var attributedText: NSAttributedString! { didSet { textDidChange() } } override public var textContainerInset: UIEdgeInsets { didSet { updateConstraintsForPlaceholderLabel() } } override public init(frame: CGRect, textContainer: NSTextContainer?) { super.init(frame: frame, textContainer: textContainer) commonInit() } required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } private func commonInit() { NotificationCenter.default.addObserver(self, selector: #selector(textDidChange), name: NSNotification.Name.UITextViewTextDidChange, object: nil) placeholderLabel.font = font placeholderLabel.textColor = placeholderColor placeholderLabel.textAlignment = textAlignment placeholderLabel.text = placeholder placeholderLabel.numberOfLines = 0 placeholderLabel.backgroundColor = UIColor.clear placeholderLabel.translatesAutoresizingMaskIntoConstraints = false addSubview(placeholderLabel) updateConstraintsForPlaceholderLabel() } private func updateConstraintsForPlaceholderLabel() { var newConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-(\(textContainerInset.left + textContainer.lineFragmentPadding))-[placeholder]", options: [], metrics: nil, views: ["placeholder": placeholderLabel]) newConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|-(\(textContainerInset.top))-[placeholder]", options: [], metrics: nil, views: ["placeholder": placeholderLabel]) newConstraints.append(NSLayoutConstraint( item: placeholderLabel, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1.0, constant: -(textContainerInset.left + textContainerInset.right + textContainer.lineFragmentPadding * 2.0) )) removeConstraints(placeholderLabelConstraints) addConstraints(newConstraints) placeholderLabelConstraints = newConstraints } @objc private func textDidChange() { placeholderLabel.isHidden = !text.isEmpty } public override func layoutSubviews() { super.layoutSubviews() placeholderLabel.preferredMaxLayoutWidth = textContainer.size.width - textContainer.lineFragmentPadding * 2.0 } deinit { NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UITextViewTextDidChange, object: nil) } 

}

我很快写了一堂课。 您需要根据需要导入此类。

由于声誉我不能添加评论。 在@clearlight答案中添加一个委托需要。

 func textViewDidBeginEditing(_ textView: UITextView) { cell.placeholderLabel.isHidden = !textView.text.isEmpty } 

是需要的

因为textViewDidChange不是第一次调用

Swift 3.1

这个扩展适用于我: https : //github.com/devxoul/UITextView-Placeholder

这是一个代码片段:

通过pod安装它:

 pod 'UITextView+Placeholder', '~> 1.2' 

将其导入您的class级

 import UITextView_Placeholder 

并添加placeholder属性到您已经创build的UITextView

 textView.placeholder = "Put some detail" 

多数民众赞成在这里,它看起来如何(第三个盒子是一个UITextView在这里输入图像描述

没有任何占位符可用于textview。 当用户在文本视图中input时,必须在其上面放置标签,然后将其隐藏或在用户input删除所有值时按默认值设置。

如果您使用多个文本视图,这是我准备好使用解决scheme

 func textViewShouldBeginEditing(textView: UITextView) -> Bool { // Set cursor to the beginning if placeholder is set if textView.textColor == UIColor.lightGrayColor() { textView.selectedTextRange = textView.textRangeFromPosition(textView.beginningOfDocument, toPosition: textView.beginningOfDocument) } return true } func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { // Remove placeholder if textView.textColor == UIColor.lightGrayColor() && text.characters.count > 0 { textView.text = "" textView.textColor = UIColor.blackColor() } if text == "\n" { textView.resignFirstResponder() return false } return true } func textViewDidChange(textView: UITextView) { // Set placeholder if text is empty if textView.text.isEmpty { textView.text = NSLocalizedString("Hint", comment: "hint") textView.textColor = UIColor.lightGrayColor() textView.selectedTextRange = textView.textRangeFromPosition(textView.beginningOfDocument, toPosition: textView.beginningOfDocument) } } func textViewDidChangeSelection(textView: UITextView) { // Set cursor to the beginning if placeholder is set let firstPosition = textView.textRangeFromPosition(textView.beginningOfDocument, toPosition: textView.beginningOfDocument) // Do not change position recursively if textView.textColor == UIColor.lightGrayColor() && textView.selectedTextRange != firstPosition { textView.selectedTextRange = firstPosition } } 

协议版本的clearlight的答案在上面,因为协议是伟大的。 在你喜欢的地方stream行。 扣篮!

 extension UITextViewPlaceholder where Self: UIViewController { // Use this in ViewController's ViewDidLoad method. func addPlaceholder(text: String, toTextView: UITextView, font: UIFont? = nil) { placeholderLabel = UILabel() placeholderLabel.text = text placeholderLabel.font = font ?? UIFont.italicSystemFont(ofSize: (toTextView.font?.pointSize)!) placeholderLabel.sizeToFit() toTextView.addSubview(placeholderLabel) placeholderLabel.frame.origin = CGPoint(x: 5, y: (toTextView.font?.pointSize)! / 2) placeholderLabel.textColor = UIColor.lightGray placeholderLabel.isHidden = !toTextView.text.isEmpty } // Use this function in the ViewController's textViewDidChange delegate method. func textViewWithPlaceholderDidChange(_ textView: UITextView) { placeholderLabel.isHidden = !textView.text.isEmpty } } 

文本查看代表方法

使用这两个委托方法,也可以在你的类中编写UITextViewDelegate

 func textViewDidBeginEditing(_ textView: UITextView) { if (commentsTextView.text == "Type Your Comments") { commentsTextView.text = nil commentsTextView.textColor = UIColor.darkGray } } func textViewDidEndEditing(_ textView: UITextView) { if commentsTextView.text.isEmpty { commentsTextView.text = "Type Your Comments" commentsTextView.textColor = UIColor.darkGray } textView.resignFirstResponder() } 
 func setPlaceholder(){ var placeholderLabel = UILabel() placeholderLabel.text = "Describe your need..." placeholderLabel.font = UIFont.init(name: "Lato-Regular", size: 15.0) ?? UIFont.boldSystemFont(ofSize: 14.0) placeholderLabel.sizeToFit() descriptionTextView.addSubview(placeholderLabel) placeholderLabel.frame.origin = CGPoint(x: 5, y: (descriptionTextView.font?.pointSize)! / 2) placeholderLabel.textColor = UIColor.lightGray placeholderLabel.isHidden = !descriptionTextView.text.isEmpty } //Delegate Method. func textViewDidChange(_ textView: UITextView) { placeholderLabel.isHidden = !textView.text.isEmpty }