在UITextView占位符

我正在做一个使用UITextView的应用程序。 现在我想让UITextView拥有一个类似于你可以为UITextField设置的占位符。

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

我对bcd的解决scheme进行了一些小修改,以允许从Xib文件进行初始化,文本换行以及保持背景颜色。 希望它能拯救别人的麻烦。

UIPlaceHolderTextView.h:

 #import <Foundation/Foundation.h> IB_DESIGNABLE @interface UIPlaceHolderTextView : UITextView @property (nonatomic, retain) IBInspectable NSString *placeholder; @property (nonatomic, retain) IBInspectable UIColor *placeholderColor; -(void)textChanged:(NSNotification*)notification; @end 

UIPlaceHolderTextView.m:

 #import "UIPlaceHolderTextView.h" @interface UIPlaceHolderTextView () @property (nonatomic, retain) UILabel *placeHolderLabel; @end @implementation UIPlaceHolderTextView CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25; - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; #if __has_feature(objc_arc) #else [_placeHolderLabel release]; _placeHolderLabel = nil; [_placeholderColor release]; _placeholderColor = nil; [_placeholder release]; _placeholder = nil; [super dealloc]; #endif } - (void)awakeFromNib { [super awakeFromNib];  // Use Interface Builder User Defined Runtime Attributes to set  // placeholder and placeholderColor in Interface Builder. if (!self.placeholder) { [self setPlaceholder:@""]; } if (!self.placeholderColor) { [self setPlaceholderColor:[UIColor lightGrayColor]]; } [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil]; } - (id)initWithFrame:(CGRect)frame { if( (self = [super initWithFrame:frame]) ) { [self setPlaceholder:@""]; [self setPlaceholderColor:[UIColor lightGrayColor]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil]; } return self; } - (void)textChanged:(NSNotification *)notification { if([[self placeholder] length] == 0) { return; } [UIView animateWithDuration:UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION animations:^{ if([[self text] length] == 0) { [[self viewWithTag:999] setAlpha:1]; } else { [[self viewWithTag:999] setAlpha:0]; } }]; } - (void)setText:(NSString *)text { [super setText:text]; [self textChanged:nil]; } - (void)drawRect:(CGRect)rect { if( [[self placeholder] length] > 0 ) { if (_placeHolderLabel == nil ) { _placeHolderLabel = [[UILabel alloc] initWithFrame:CGRectMake(8,8,self.bounds.size.width - 16,0)]; _placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping; _placeHolderLabel.numberOfLines = 0; _placeHolderLabel.font = self.font; _placeHolderLabel.backgroundColor = [UIColor clearColor]; _placeHolderLabel.textColor = self.placeholderColor; _placeHolderLabel.alpha = 0; _placeHolderLabel.tag = 999; [self addSubview:_placeHolderLabel]; } _placeHolderLabel.text = self.placeholder; [_placeHolderLabel sizeToFit]; [self sendSubviewToBack:_placeHolderLabel]; } if( [[self text] length] == 0 && [[self placeholder] length] > 0 ) { [[self viewWithTag:999] setAlpha:1]; } [super drawRect:rect]; } @end 

简单的方法,只需使用以下UITextViewDelegate方法在UITextView创build占位符文本:

 - (void)textViewDidBeginEditing:(UITextView *)textView { if ([textView.text isEqualToString:@"placeholder text here..."]) { textView.text = @""; textView.textColor = [UIColor blackColor]; //optional } [textView becomeFirstResponder]; } - (void)textViewDidEndEditing:(UITextView *)textView { if ([textView.text isEqualToString:@""]) { textView.text = @"placeholder text here..."; textView.textColor = [UIColor lightGrayColor]; //optional } [textView resignFirstResponder]; } 

只要记住设置myUITextView创build的确切文字,例如

 UITextView *myUITextView = [[UITextView alloc] init]; myUITextView.delegate = self; myUITextView.text = @"placeholder text here..."; myUITextView.textColor = [UIColor lightGrayColor]; //optional 

并在包含这些方法之前使父类成为UITextViewDelegate

 @interface MyClass () <UITextViewDelegate> @end 

代码Swift 3.1

 func textViewDidBeginEditing(_ textView: UITextView) { if (textView.text == "placeholder text here...") { textView.text = "" textView.textColor = .black } textView.becomeFirstResponder() //Optional } func textViewDidEndEditing(_ textView: UITextView) { if (textView.text == "") { textView.text = "placeholder text here..." textView.textColor = .lightGray } textView.resignFirstResponder() } 

只要记住设置myUITextView创build的确切文字,例如

  let myUITextView = UITextView.init() myUITextView.delegate = self myUITextView.text = "placeholder text here..." myUITextView.textColor = .lightGray 

并在包含这些方法之前使父类成为UITextViewDelegate

 class MyClass: UITextViewDelegate { } 

我不太满意任何发布的解决scheme,因为它们有点沉重。 将视图添加到视图并不是很理想(特别是在drawRect: )。 他们都有泄漏,这也是不能接受的。

这是我的解决scheme: SAMTextView

SAMTextView.h

 // // SAMTextView.h // SAMTextView // // Created by Sam Soffes on 8/18/10. // Copyright 2010-2013 Sam Soffes. All rights reserved. // #import <UIKit/UIKit.h> /** UITextView subclass that adds placeholder support like UITextField has. */ @interface SAMTextView : UITextView /** The string that is displayed when there is no other text in the text view. The default value is `nil`. */ @property (nonatomic, strong) NSString *placeholder; /** The color of the placeholder. The default is `[UIColor lightGrayColor]`. */ @property (nonatomic, strong) UIColor *placeholderTextColor; /** Returns the drawing rectangle for the text views's placeholder text. @param bounds The bounding rectangle of the receiver. @return The computed drawing rectangle for the placeholder text. */ - (CGRect)placeholderRectForBounds:(CGRect)bounds; @end 

SAMTextView.m

 // // SAMTextView.m // SAMTextView // // Created by Sam Soffes on 8/18/10. // Copyright 2010-2013 Sam Soffes. All rights reserved. // #import "SAMTextView.h" @implementation SAMTextView #pragma mark - Accessors @synthesize placeholder = _placeholder; @synthesize placeholderTextColor = _placeholderTextColor; - (void)setText:(NSString *)string { [super setText:string]; [self setNeedsDisplay]; } - (void)insertText:(NSString *)string { [super insertText:string]; [self setNeedsDisplay]; } - (void)setAttributedText:(NSAttributedString *)attributedText { [super setAttributedText:attributedText]; [self setNeedsDisplay]; } - (void)setPlaceholder:(NSString *)string { if ([string isEqual:_placeholder]) { return; } _placeholder = string; [self setNeedsDisplay]; } - (void)setContentInset:(UIEdgeInsets)contentInset { [super setContentInset:contentInset]; [self setNeedsDisplay]; } - (void)setFont:(UIFont *)font { [super setFont:font]; [self setNeedsDisplay]; } - (void)setTextAlignment:(NSTextAlignment)textAlignment { [super setTextAlignment:textAlignment]; [self setNeedsDisplay]; } #pragma mark - NSObject - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:self]; } #pragma mark - UIView - (id)initWithCoder:(NSCoder *)aDecoder { if ((self = [super initWithCoder:aDecoder])) { [self initialize]; } return self; } - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { [self initialize]; } return self; } - (void)drawRect:(CGRect)rect { [super drawRect:rect]; if (self.text.length == 0 && self.placeholder) { rect = [self placeholderRectForBounds:self.bounds]; UIFont *font = self.font ? self.font : self.typingAttributes[NSFontAttributeName]; // Draw the text [self.placeholderTextColor set]; [self.placeholder drawInRect:rect withFont:font lineBreakMode:NSLineBreakByTruncatingTail alignment:self.textAlignment]; } } #pragma mark - Placeholder - (CGRect)placeholderRectForBounds:(CGRect)bounds { // Inset the rect CGRect rect = UIEdgeInsetsInsetRect(bounds, self.contentInset); if (self.typingAttributes) { NSParagraphStyle *style = self.typingAttributes[NSParagraphStyleAttributeName]; if (style) { rect.origin.x += style.headIndent; rect.origin.y += style.firstLineHeadIndent; } } return rect; } #pragma mark - Private - (void)initialize { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:self]; self.placeholderTextColor = [UIColor colorWithWhite:0.702f alpha:1.0f]; } - (void)textChanged:(NSNotification *)notification { [self setNeedsDisplay]; } @end 

这比其他的简单得多,因为它不使用子视图(或泄漏)。 随意使用它。

11/11/11更新:它现在被logging并支持在Interface Builder中使用。

更新11/24/13:指向新的回购。

你可以做的是在text属性中设置具有一些初始值的文本视图,并将textColor更改为[UIColor grayColor]或类似的东西。 然后,每当文本视图变为可编辑时,清除文本并显示一个光标,如果文本字段再次为空,则放置占位符文本。 根据需要将颜色更改为[UIColor blackColor]

它与UITextField中的占位符function不完全相同,但是非常接近。

我发现自己模仿一个地方持有人是一个非常简单的方法

  1. 在NIB或代码中,将textView的textColor设置为lightGrayColor(大部分时间)
  2. 确保你的textView的委托链接到文件的所有者,并在头文件中实现UITextViewDelegate
  3. 设置你的textview的默认文本(例如:“Foobar占位符”)
  4. 实现:( BOOL)textViewShouldBeginEditing:(UITextView *)textView

编辑:

更改if语句来比较标签而不是文本。 如果用户删除了他们的文本,也有可能也意外地删除了@"Foobar placeholder"的一部分@"Foobar placeholder" 。这意味着如果用户重新input了textView的下面的委托方法, -(BOOL) textViewShouldBeginEditing:(UITextView *) textView ,它不会按预期工作。 我试着用if语句中的文本颜色进行比较,但是发现界面生成器中设置的浅灰色与使用[UIColor lightGreyColor]设置的浅灰色[UIColor lightGreyColor]

 - (BOOL) textViewShouldBeginEditing:(UITextView *)textView { if(textView.tag == 0) { textView.text = @""; textView.textColor = [UIColor blackColor]; textView.tag = 1; } return YES; } 

当键盘返回并且[textView长度] == 0时,也可以重置占位符文本

编辑:

只是为了让最后一部分更清楚 – 这里是如何设置占位符文本:

 - (void)textViewDidChange:(UITextView *)textView { if([textView.text length] == 0) { textView.text = @"Foobar placeholder"; textView.textColor = [UIColor lightGrayColor]; textView.tag = 0; } } 

你可以通过设置UITextView上的标签

 [UITextView addSubView:lblPlaceHoldaer]; 

并将其隐藏在TextViewdidChange方法上。

这是简单和容易的方法。

如果有人需要Swift的解决scheme:

将UITextViewDelegate添加到您的类

 var placeHolderText = "Placeholder Text..." override func viewDidLoad() { super.viewDidLoad() textView.delegate = self } func textViewShouldBeginEditing(textView: UITextView) -> Bool { self.textView.textColor = UIColor.blackColor() if(self.textView.text == placeHolderText) { self.textView.text = "" } return true } func textViewDidEndEditing(textView: UITextView) { if(textView.text == "") { self.textView.text = placeHolderText self.textView.textColor = UIColor.lightGrayColor() } } override func viewWillAppear(animated: Bool) { if(currentQuestion.answerDisplayValue == "") { self.textView.text = placeHolderText self.textView.textColor = UIColor.lightGrayColor() } else { self.textView.text = "xxx" // load default text / or stored self.textView.textColor = UIColor.blackColor() } } 

我扩展了KmKndy的答案,使占位符保持可见,直到用户开始编辑UITextView而不是点击它。 这反映了Twitter和Facebook应用程序中的function。 我的解决scheme不需要你的子类和工作,如果用户直接input或粘贴文本!

占位符的例子Twitter应用程序

 - (void)textViewDidChangeSelection:(UITextView *)textView{ if ([textView.text isEqualToString:@"What's happening?"] && [textView.textColor isEqual:[UIColor lightGrayColor]])[textView setSelectedRange:NSMakeRange(0, 0)]; } - (void)textViewDidBeginEditing:(UITextView *)textView{ [textView setSelectedRange:NSMakeRange(0, 0)]; } - (void)textViewDidChange:(UITextView *)textView { if (textView.text.length != 0 && [[textView.text substringFromIndex:1] isEqualToString:@"What's happening?"] && [textView.textColor isEqual:[UIColor lightGrayColor]]){ textView.text = [textView.text substringToIndex:1]; textView.textColor = [UIColor blackColor]; //optional } else if(textView.text.length == 0){ textView.text = @"What's happening?"; textView.textColor = [UIColor lightGrayColor]; [textView setSelectedRange:NSMakeRange(0, 0)]; } } - (void)textViewDidEndEditing:(UITextView *)textView { if ([textView.text isEqualToString:@""]) { textView.text = @"What's happening?"; textView.textColor = [UIColor lightGrayColor]; //optional } [textView resignFirstResponder]; } - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{ if (textView.text.length > 1 && [textView.text isEqualToString:@"What's happening?"]) { textView.text = @""; textView.textColor = [UIColor blackColor]; } return YES; } 

只要记住设置myUITextView创build的确切文字,例如

 UITextView *myUITextView = [[UITextView alloc] init]; myUITextView.delegate = self; myUITextView.text = @"What's happening?"; myUITextView.textColor = [UIColor lightGrayColor]; //optional 

并在包含这些方法之前使父类成为UITextView委托

 @interface MyClass () <UITextViewDelegate> @end 

简单的Swift 3解决scheme

UITextViewDelegate添加到您的类

设置yourTextView.delegate = self

创buildplaceholderLabel并将其放置在yourTextView

现在只需在textViewDidChange上设置placeholderLabel.alpha

  // MARK: TextView Delegate func textViewDidChange(_ textView: UITextView) { UIView.animate(withDuration: 0.3) { self.placeholderLabel.alpha = textView.text.isEmpty ? 1 : 0 } } 

你可能需要使用placeholderLabel位置来设置它的权利,但这不应该太难

我build议使用SZTextView

https://github.com/glaszig/SZTextView

storyboard添加默认的UITextView ,然后将其自定义类更改为SZTextView如下所示

在这里输入图像描述

然后你会在Attribute Inspector看到两个新的选项

在这里输入图像描述

这是我做到的:

UITextView2.h

 #import <UIKit/UIKit.h> @interface UITextView2 : UITextView <UITextViewDelegate> { NSString *placeholder; UIColor *placeholderColor; } @property(nonatomic, retain) NSString *placeholder; @property(nonatomic, retain) UIColor *placeholderColor; -(void)textChanged:(NSNotification*)notif; @end 

UITextView2.m

 @implementation UITextView2 @synthesize placeholder, placeholderColor; - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { [self setPlaceholder:@""]; [self setPlaceholderColor:[UIColor lightGrayColor]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil]; } return self; } -(void)textChanged:(NSNotification*)notif { if ([[self placeholder] length]==0) return; if ([[self text] length]==0) { [[self viewWithTag:999] setAlpha:1]; } else { [[self viewWithTag:999] setAlpha:0]; } } - (void)drawRect:(CGRect)rect { if ([[self placeholder] length]>0) { UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(8, 8, 0, 0)]; [l setFont:self.font]; [l setTextColor:self.placeholderColor]; [l setText:self.placeholder]; [l setAlpha:0]; [l setTag:999]; [self addSubview:l]; [l sizeToFit]; [self sendSubviewToBack:l]; [l release]; } if ([[self text] length]==0 && [[self placeholder] length]>0) { [[self viewWithTag:999] setAlpha:1]; } [super drawRect:rect]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } @end 

这是一个简单易行的解决scheme,其行为与UITextField的占位符完全相同,但不需要绘制自定义视图或退出第一响应者。

 - (void) textViewDidChange:(UITextView *)textView{ if (textView.text.length == 0){ textView.textColor = [UIColor lightGrayColor]; textView.text = placeholderText; [textView setSelectedRange:NSMakeRange(0, 0)]; isPlaceholder = YES; } else if (isPlaceholder && ![textView.text isEqualToString:placeholderText]) { textView.text = [textView.text substringToIndex:1]; textView.textColor = [UIColor blackColor]; isPlaceholder = NO; } } 

(在else if语句中的第二个检查是针对没有input任何内容并且用户按下退格的情况)

只需将您的类设置为UITextViewDelegate即可。 在viewDidLoad中,你应该像初始化一样

 - (void) viewDidLoad{ // initialize placeholder text placeholderText = @"some placeholder"; isPlaceholder = YES; self.someTextView.text = placeholderText; self.someTextView.textColor = [UIColor lightGrayColor]; [self.someTextView setSelectedRange:NSMakeRange(0, 0)]; // assign UITextViewDelegate self.someTextView.delegate = self; } 

对不起,添加另一个答案,但我只是拉了这样的事情,这创造了最接近于UITextField种类的占位符。

希望这有助于某人。

 -(void)textViewDidChange:(UITextView *)textView{ if(textView.textColor == [UIColor lightGrayColor]){ textView.textColor = [UIColor blackColor]; // look at the comment section in this answer textView.text = [textView.text substringToIndex: 0];// look at the comment section in this answer }else if(textView.text.length == 0){ textView.text = @"This is some placeholder text."; textView.textColor = [UIColor lightGrayColor]; textView.selectedRange = NSMakeRange(0, 0); } } -(void)textViewDidChangeSelection:(UITextView *)textView{ if(textView.textColor == [UIColor lightGrayColor] && (textView.selectedRange.location != 0 || textView.selectedRange.length != 0)){ textView.selectedRange = NSMakeRange(0, 0); } } 

下面是一个Swift端口的“SAMTextView”ObjC代码张贴作为第一个问题的答案之一。 我在iOS 8上进行了testing。我调整了一些东西,包括占位符文本的位置偏移,因为原文太高,太正确了(对该文章的其中一条注释中使用了build议)。

我知道有很多简单的解决scheme,但是我喜欢UITextView的子类化方法,因为它是可重用的,而且我不需要在机制中使用它。

Swift 2.2:

 import UIKit class PlaceholderTextView: UITextView { @IBInspectable var placeholderColor: UIColor = UIColor.lightGrayColor() @IBInspectable var placeholderText: String = "" override var font: UIFont? { didSet { setNeedsDisplay() } } override var contentInset: UIEdgeInsets { didSet { setNeedsDisplay() } } override var textAlignment: NSTextAlignment { didSet { setNeedsDisplay() } } override var text: String? { didSet { setNeedsDisplay() } } override var attributedText: NSAttributedString? { didSet { setNeedsDisplay() } } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setUp() } override init(frame: CGRect, textContainer: NSTextContainer?) { super.init(frame: frame, textContainer: textContainer) } private func setUp() { NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PlaceholderTextView.textChanged(_:)), name: UITextViewTextDidChangeNotification, object: self) } func textChanged(notification: NSNotification) { setNeedsDisplay() } func placeholderRectForBounds(bounds: CGRect) -> CGRect { var x = contentInset.left + 4.0 var y = contentInset.top + 9.0 let w = frame.size.width - contentInset.left - contentInset.right - 16.0 let h = frame.size.height - contentInset.top - contentInset.bottom - 16.0 if let style = self.typingAttributes[NSParagraphStyleAttributeName] as? NSParagraphStyle { x += style.headIndent y += style.firstLineHeadIndent } return CGRect(x: x, y: y, width: w, height: h) } override func drawRect(rect: CGRect) { if text!.isEmpty && !placeholderText.isEmpty { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = textAlignment let attributes: [ String: AnyObject ] = [ NSFontAttributeName : font!, NSForegroundColorAttributeName : placeholderColor, NSParagraphStyleAttributeName : paragraphStyle] placeholderText.drawInRect(placeholderRectForBounds(bounds), withAttributes: attributes) } super.drawRect(rect) } } 

在一些代码行中使用这个简单的方法:

在.nib中将一个标签添加到UITextView中,然后将此标签连接到您的代码。

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{ if (range.location>0 || text.length!=0) { placeholderLabel1.hidden = YES; }else{ placeholderLabel1.hidden = NO; } return YES; } 

我已经修改了Sam Soffes的实现来使用iOS7:

 - (void)drawRect:(CGRect)rect { [super drawRect:rect]; if (_shouldDrawPlaceholder) { UIEdgeInsets insets = self.textContainerInset; CGRect placeholderRect = CGRectMake( insets.left + self.textContainer.lineFragmentPadding, insets.top, self.frame.size.width - insets.left - insets.right, self.frame.size.height - insets.top - insets.bottom); [_placeholderText drawWithRect:placeholderRect options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine attributes:self.placeholderAttributes context:nil]; } } - (NSDictionary *)placeholderAttributes { if (_placeholderAttributes == nil) { _placeholderAttributes = @ { NSFontAttributeName : self.font, NSForegroundColorAttributeName : self.placeholderColor }; } return _placeholderAttributes; } 

请记住在可能会更改可能影响它们的字体和其他行为的方法中设置_placeholderAttribues = nil 。 如果这不影响你的话,你可能还想跳过属性字典的“懒惰”制作。

编辑:

请记住在setBounds的重写版本中调用setNeedsDisplay,如果您希望占位符在自动布局animation等之后看起来不错。

你也可以创build一个新的类TextViewWithPlaceholder作为UITextView的子类。

(这个代码很粗糙 – 但我认为它是在正确的轨道上。)

 @interface TextViewWithPlaceholder : UITextView { NSString *placeholderText; // make a property UIColor *placeholderColor; // make a property UIColor *normalTextColor; // cache text color here whenever you switch to the placeholderColor } - (void) setTextColor: (UIColor*) color { normalTextColor = color; [super setTextColor: color]; } - (void) updateForTextChange { if ([self.text length] == 0) { normalTextColor = self.textColor; self.textColor = placeholderColor; self.text = placeholderText; } else { self.textColor = normalTextColor; } } 

在你的委托中,添加这个:

 - (void)textViewDidChange:(UITextView *)textView { if ([textView respondsToSelector: @selector(updateForTextChange)]) { [textView updateForTextChange]; } } 

我做了我自己的“UITextView”的子类的版本。 我喜欢Sam Soffes使用通知的想法,但我不喜欢drawRect:覆盖。 看来对我来说过分了。 我想我做了一个非常干净的实现。

你可以在这里看我的子类。 演示项目也包括在内。

您好可以使用IQKeyboard Manager中提供的IQTextView它很容易使用和集成您的文本视图到IQTextView的设置类,您可以使用它的属性来设置所需颜色的占位符标签。 您可以从IQKeyboardManager下载库

或者你可以从cocoapods安装它。

First take a label in .h file.

Here I take

 UILabel * lbl; 

Then in .m under viewDidLoad declare it

 lbl = [[UILabel alloc] initWithFrame:CGRectMake(8.0, 0.0,250, 34.0)]; lbl.font=[UIFont systemFontOfSize:14.0]; [lbl setText:@"Write a message..."]; [lbl setBackgroundColor:[UIColor clearColor]]; [lbl setTextColor:[UIColor lightGrayColor]]; [textview addSubview:lbl]; 

textview is my TextView.

Now declare

 -(void)textViewDidChange:(UITextView *)textView { if (![textView hasText]){ lbl.hidden = NO; } else{ lbl.hidden = YES; } } 

And your Textview placeholder is ready !

  - (void)textViewDidChange:(UITextView *)textView { placeholderLabel.hidden = YES; } 

put a label over the textview.

Here's yet another way to do it, one that reproduces the slight indentation of UITextField 's placeholder:

Drag a UITextField right under the UITextView so that their top left corners are aligned. Add your placeholder text to the text field.

In viewDidLoad, add:

 [tView setDelegate:self]; tView.contentInset = UIEdgeInsetsMake(-8,-8,0,0); tView.backgroundColor = [UIColor clearColor]; 

然后添加:

 - (void)textViewDidChange:(UITextView *)textView { if (textView.text.length == 0) { textView.backgroundColor = [UIColor clearColor]; } else { textView.backgroundColor = [UIColor whiteColor]; } } 

Lets make it easy

Create one UILabel and place it on your text view(Give the text as Placeholder-set color gray-you can do all this in your xib) Now in you header file declare the UILabel and also the the textviewDelegate Now you can simply hide the label when you click on the textview

complete code below

 @interface ViewController :UIViewController<UITextViewDelegate>{ } @property (nonatomic,strong) IBOutlet UILabel *PlceHolder_label; @property (nonatomic,strong) IBOutlet UITextView *TextView; @end 

implementation

 @implementation UploadFoodImageViewController @synthesize PlceHolder_label,TextView; - (void)viewDidLoad { [super viewDidLoad]; } - (BOOL)textViewShouldBeginEditing:(UITextView *)textView{ if([textView isEqual:TextView]){ [PlceHolder_label setHidden:YES]; [self.tabScrlVw setContentOffset:CGPointMake(0,150) animated:YES]; } return YES; } 

@end

Dont forget to connect the textView and UILabel to filesowner from xib

Take a look at UTPlaceholderTextView .

This is a convenient subclass of UITextView that supports placeholder similiar to that of UITextField. Main peculiarities:

  • Does not use subviews
  • Does not override drawRect:
  • Placeholder could be of arbitrary length, and rendered just the same way as usual text

This thread has had plenty of answers, but here's the version I prefer.

It extends the existing UITextView class so is easily reuseable, and it doesn't intercept the events like textViewDidChange (which might break user's code, if they were already intercepting these events elsewhere).

Using my code (shown below), you can easily add a placeholder to any of your UITextViews like this:

 self.textViewComments.placeholder = @"(Enter some comments here.)"; 

When you set this new placeholder value, it quietly adds a UILabel on top of your UITextView , then hide/shows it as necessary:

在这里输入图像描述

Okay, to make these changes, add a "UITextViewHelper.h" file containing this code:

 // UITextViewHelper.h // Created by Michael Gledhill on 13/02/15. #import <Foundation/Foundation.h> @interface UITextView (UITextViewHelper) @property (nonatomic, strong) NSString* placeholder; @property (nonatomic, strong) UILabel* placeholderLabel; @property (nonatomic, strong) NSString* textValue; -(void)checkIfNeedToDisplayPlaceholder; @end 

…and a UITextViewHelper.m file containing this:

 // UITextViewHelper.m // Created by Michael Gledhill on 13/02/15. // // This UITextView category allows us to easily display a PlaceHolder string in our UITextView. // The downside is that, your code needs to set the "textValue" rather than the "text" value to safely set the UITextView's text. // #import "UITextViewHelper.h" #import <objc/runtime.h> @implementation UITextView (UITextViewHelper) #define UI_PLACEHOLDER_TEXT_COLOR [UIColor colorWithRed:170.0/255.0 green:170.0/255.0 blue:170.0/255.0 alpha:1.0] @dynamic placeholder; @dynamic placeholderLabel; @dynamic textValue; -(void)setTextValue:(NSString *)textValue { // Change the text of our UITextView, and check whether we need to display the placeholder. self.text = textValue; [self checkIfNeedToDisplayPlaceholder]; } -(NSString*)textValue { return self.text; } -(void)checkIfNeedToDisplayPlaceholder { // If our UITextView is empty, display our Placeholder label (if we have one) if (self.placeholderLabel == nil) return; self.placeholderLabel.hidden = (![self.text isEqualToString:@""]); } -(void)onTap { // When the user taps in our UITextView, we'll see if we need to remove the placeholder text. [self checkIfNeedToDisplayPlaceholder]; // Make the onscreen keyboard appear. [self becomeFirstResponder]; } -(void)keyPressed:(NSNotification*)notification { // The user has just typed a character in our UITextView (or pressed the delete key). // Do we need to display our Placeholder label ? [self checkIfNeedToDisplayPlaceholder]; } #pragma mark - Add a "placeHolder" string to the UITextView class NSString const *kKeyPlaceHolder = @"kKeyPlaceHolder"; -(void)setPlaceholder:(NSString *)_placeholder { // Sets our "placeholder" text string, creates a new UILabel to contain it, and modifies our UITextView to cope with // showing/hiding the UILabel when needed. objc_setAssociatedObject(self, &kKeyPlaceHolder, (id)_placeholder, OBJC_ASSOCIATION_RETAIN_NONATOMIC); self.placeholderLabel = [[UILabel alloc] initWithFrame:self.frame]; self.placeholderLabel.numberOfLines = 1; self.placeholderLabel.text = _placeholder; self.placeholderLabel.textColor = UI_PLACEHOLDER_TEXT_COLOR; self.placeholderLabel.backgroundColor = [UIColor clearColor]; self.placeholderLabel.userInteractionEnabled = true; self.placeholderLabel.font = self.font; [self addSubview:self.placeholderLabel]; [self.placeholderLabel sizeToFit]; // Whenever the user taps within the UITextView, we'll give the textview the focus, and hide the placeholder if necessary. [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap)]]; // Whenever the user types something in the UITextView, we'll see if we need to hide/show the placeholder label. [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(keyPressed:) name:UITextViewTextDidChangeNotification object:nil]; [self checkIfNeedToDisplayPlaceholder]; } -(NSString*)placeholder { // Returns our "placeholder" text string return objc_getAssociatedObject(self, &kKeyPlaceHolder); } #pragma mark - Add a "UILabel" to this UITextView class NSString const *kKeyLabel = @"kKeyLabel"; -(void)setPlaceholderLabel:(UILabel *)placeholderLabel { // Stores our new UILabel (which contains our placeholder string) objc_setAssociatedObject(self, &kKeyLabel, (id)placeholderLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(keyPressed:) name:UITextViewTextDidChangeNotification object:nil]; [self checkIfNeedToDisplayPlaceholder]; } -(UILabel*)placeholderLabel { // Returns our new UILabel return objc_getAssociatedObject(self, &kKeyLabel); } @end 

Yup, it's a lot of code, but once you've added it to your project and included the .h file…

 #import "UITextViewHelper.h" 

…you can easily use placeholders in UITextViews .

There's one gotcha though.

如果你这样做:

 self.textViewComments.placeholder = @"(Enter some comments here.)"; self.textViewComments.text = @"Ooooh, hello there"; 

…the placeholder will appear on top of the text. When you set the text value, none of the regular notifications gets called, so I couldn't work out how to call my function to decide whether to show/hide the placeholder.

The solution is to set the textValue rather than text :

 self.textViewComments.placeholder = @"(Enter some comments here.)"; self.textViewComments.textValue = @"Ooooh, hello there"; 

Alternatively, you can set the text value, then call checkIfNeedToDisplayPlaceholder .

 self.textViewComments.text = @"Ooooh, hello there"; [self.textViewComments checkIfNeedToDisplayPlaceholder]; 

I like solutions like this, as they "fill the gap" between what Apple provides us with, and what we (as developers) actually need in our apps. You write this code once, add it to your library of "helper" .m/.h files, and, over time, the SDK actually starts becoming less frustrating.

(I wrote a similar helper for adding a "clear" button to my UITextViews, another thing which annoyingly exists in UITextField but not in UITextView …)

It is not possible to create placeholder in UITextView but you can generate effect like place holder by this.

  - (void)viewDidLoad{ commentTxtView.text = @"Comment"; commentTxtView.textColor = [UIColor lightGrayColor]; commentTxtView.delegate = self; } - (BOOL) textViewShouldBeginEditing:(UITextView *)textView { commentTxtView.text = @""; commentTxtView.textColor = [UIColor blackColor]; return YES; } -(void) textViewDidChange:(UITextView *)textView { if(commentTxtView.text.length == 0){ commentTxtView.textColor = [UIColor lightGrayColor]; commentTxtView.text = @"Comment"; [commentTxtView resignFirstResponder]; } } 

OR you can add label in textview just like

  lbl = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 0.0,textView.frame.size.width - 10.0, 34.0)]; [lbl setText:kDescriptionPlaceholder]; [lbl setBackgroundColor:[UIColor clearColor]]; [lbl setTextColor:[UIColor lightGrayColor]]; textView.delegate = self; [textView addSubview:lbl]; 

and set

 - (void)textViewDidEndEditing:(UITextView *)theTextView { if (![textView hasText]) { lbl.hidden = NO; } } - (void) textViewDidChange:(UITextView *)textView { if(![textView hasText]) { lbl.hidden = NO; } else{ lbl.hidden = YES; } } 

How to insert placeholder in UITextView?

The answer of PJR works like a charm. The ones here didn't work for me. Maybe an iOS5 thing.

OK my ansewer is a bit different I create a small class to do it for you.

TextViewShader.m file

 #import "TextViewShader.h" @implementation TextViewShader -(id)initWithShadedTextView:(NSString *)text textViewToShade:(UITextView *)textview { self = [super initWithFrame:textview.frame]; if (self) { if (shadeLabel==nil) { shadeLabel= [[UILabel alloc]initWithFrame:CGRectMake(10, 0, textview.frame.size.width, 30)]; } shadeLabel.text =text;// @"Enter Your Support Request"; shadeLabel.textColor = [UIColor lightGrayColor]; [textview setDelegate: self]; [textview addSubview:shadeLabel]; } return self; } -(void)textViewDidChange:(UITextView *)textView{ if (textView.text.length==0) { shadeLabel.hidden=false; } else { shadeLabel.hidden=true; } } @end 

TextViewShader.h file

 #import <UIKit/UIKit.h> @interface TextViewShader : UIView<UITextViewDelegate>{ UILabel *shadeLabel; } -(id)initWithShadedTextView:(NSString *)text textViewToShade:(UITextView *)textview ; @end 

this is the simple one line of code usage (dont forget to add #import "TextViewShader.h")

  TextViewShader* shader = [[TextViewShader alloc]initWithShadedTextView:@"Enter Your Support Request" textViewToShade: youruitextviewToshade]; 

玩的开心 :)

I created an instance variable to check whether I'll show the placeholder or not:

 BOOL showPlaceHolder; UITextView * textView; // and also the textView 

On viewDidLoad I set:

 [self setPlaceHolder]; 

Here's what this does:

 - (void)setPlaceholder { textView.text = NSLocalizedString(@"Type your question here", @"placeholder"); textView.textColor = [UIColor lightGrayColor]; self.showPlaceHolder = YES; //we save the state so it won't disappear in case you want to re-edit it } 

I also created a button to resign the keyboard. You don't have to do this but the cool thing here is that the placeholder is shown again if nothing was entered

 - (void)textViewDidBeginEditing:(UITextView *)txtView { self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(resignKeyboard)]; if (self.showPlaceHolder == YES) { textView.textColor = [UIColor blackColor]; textView.text = @""; self.showPlaceHolder = NO; } } - (void)resignKeyboard { [textView resignFirstResponder]; //here if you created a button like I did to resign the keyboard, you should hide it if (textView.text.length == 0) { [self setPlaceholder]; } } 

This mimics UITextField's placeholder perfectly, where the place holder text stays until you actually type something.

 private let placeholder = "Type here" @IBOutlet weak var textView: UITextView! { didSet { textView.textColor = UIColor.lightGray textView.text = placeholder textView.selectedRange = NSRange(location: 0, length: 0) } } extension ViewController: UITextViewDelegate { func textViewDidChangeSelection(_ textView: UITextView) { // Move cursor to beginning on first tap if textView.text == placeholder { textView.selectedRange = NSRange(location: 0, length: 0) } } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if textView.text == placeholder && !text.isEmpty { textView.text = nil textView.textColor = UIColor.black textView.selectedRange = NSRange(location: 0, length: 0) } return true } func textViewDidChange(_ textView: UITextView) { if textView.text.isEmpty { textView.textColor = UIColor.lightGray textView.text = placeholder } } }