我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
当前回答
我找到了一个很容易模仿占位符的方法
在NIB或代码设置你的textView的textColor为lightGrayColor(大多数时候) 确保你的textView的委托链接到文件的所有者和实现UITextViewDelegate在你的头文件 将文本视图的默认文本设置为(例如:"Foobar placeholder") 实现:(BOOL) textViewShouldBeginEditing:(UITextView *)textView
编辑:
Changed if statements to compare tags rather than text. If the user deleted their text it was possible to also accidentally delete a portion of the place holder @"Foobar placeholder".This meant if the user re-entered the textView the following delegate method, -(BOOL) textViewShouldBeginEditing:(UITextView *) textView, it would not work as expected. I tried comparing by the color of the text in the if statement but found that light grey color set in interface builder is not the same as light grey color set in code with [UIColor lightGreyColor]
- (BOOL) textViewShouldBeginEditing:(UITextView *)textView
{
if(textView.tag == 0) {
textView.text = @"";
textView.textColor = [UIColor blackColor];
textView.tag = 1;
}
return YES;
}
当键盘返回并且[textView length] == 0时,也可以重置占位符文本
编辑:
只是为了让最后一部分更清楚——下面是如何将占位符文本设置回去:
- (void)textViewDidChange:(UITextView *)textView
{
if([textView.text length] == 0)
{
textView.text = @"Foobar placeholder";
textView.textColor = [UIColor lightGrayColor];
textView.tag = 0;
}
}
其他回答
斯威夫特3.1
在尝试了所有快速的答案之后,这个答案将为我节省3个小时的研究时间。希望这能有所帮助。
确保你的textField(不管你有什么自定义名称)指向它在Storyboard中的委托,并且有一个@IBOutlet和你的customtextfield 将以下内容添加到viewDidLoad()中,加载视图时会出现:
告诉我什么看起来是占位符:
yourCustomTextField = "Start typing..."
yourCustomTextField.textColor = .lightGray
在viewDidLoad外部但在同一个类内部添加以下声明:UIViewController, UITextViewDelegate, UINavigationControllerDelegate
这段代码将使yourCustomTextField在输入textField时消失:
func textViewDidBeginEditing (_ textView: UITextView) {
if (textView.text == "Start typing...") {
textView.text = ""
textView.textColor = .black
}
textView.becomeFirstResponder()
}
func textViewDidEndEditing(_ textView: UITextView) {
if (textView.text == "") {
textView.text = "Start typing..."
textView.textColor = .lightGray
}
textView.resignFirstResponder()
}
After looking through (and trying out) most of the proposed solutions to this seemingly obvious - but missing - feature of UITextView, the 'best' closest I found was that from BobDickinson. But I didnt like having to resort to a whole new subclass [I prefer drop-in categories for such simple functional additions], nor that it intercepted UITextViewDelegate methods, which is probably going to mess up your existing UITextView handling code. So here's my take on a drop-in category that'll work on any existing UITextView instance...
#import <objc/runtime.h>
// Private subclass needed to override placeholderRectForBounds: to correctly position placeholder
@interface _TextField : UITextField
@property UIEdgeInsets insets;
@end
@implementation _TextField
- (CGRect)placeholderRectForBounds:(CGRect)bounds
{
CGRect rect = [super placeholderRectForBounds:bounds];
return UIEdgeInsetsInsetRect(rect, _insets);
}
@end
@implementation UITextView (Placeholder)
static const void *KEY;
- (void)setPlaceholder:(NSString *)placeholder
{
_TextField *textField = objc_getAssociatedObject(self, &KEY);
if (!textField) {
textField = [_TextField.alloc initWithFrame:self.bounds];
textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
textField.userInteractionEnabled = NO;
textField.font = self.font;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
textField.insets = UIEdgeInsetsMake(self.textContainerInset.top,
self.textContainerInset.left + self.textContainer.lineFragmentPadding,
self.textContainerInset.bottom,
self.textContainerInset.right);
[self addSubview:textField];
[self sendSubviewToBack:textField];
objc_setAssociatedObject(self, &KEY, textField, OBJC_ASSOCIATION_RETAIN);
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updatePlaceholder:) name:UITextViewTextDidChangeNotification object:nil];
}
textField.placeholder = placeholder;
}
- (NSString*)placeholder
{
UITextField *textField = objc_getAssociatedObject(self, &KEY);
return textField.placeholder;
}
- (void)updatePlaceholder:(NSNotification *)notification
{
UITextField *textField = objc_getAssociatedObject(self, &KEY);
textField.font = self.font;
[textField setAlpha:self.text.length? 0 : 1];
}
@end
它使用简单,只是显而易见的
UITextView *myTextView = UITextView.new;
...
myTextView.placeholder = @"enter text here";
它通过添加一个UITextField -在正确的位置-在你的UITextView后面,并利用它的占位符代替(因此你不必担心得到正确的颜色等),然后监听通知,每当你的UITextView被改变显示/隐藏这个UITextField(因此它不会干扰你现有的UITextViewDelegate调用)。这里面没有什么神奇的数字……: -)
objc_setAssociatedObject()/objc_getAssociatedObject()是为了避免必须子类化UITextView。[不幸的是,要正确地定位UITextField,有必要引入一个'private'子类,以覆盖placeholderRectForBounds:]
改编自BobDickinson的斯威夫特回答。
你可以在textview上设置一个标签。
MyUITextView.h
@interface MyUITextView : UITextView {
UILabel* _placeholderLabel;
}
@property(nonatomic, assign)NSString *placeholder;
MyUITextView.m
@implementation MyUITextView
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Create placeholder
viewFrame = CGRectMake(0, 0, frame.size.width, 15);
_placeholderLabel = [[UILabel alloc] initWithFrame:viewFrame];
_placeholderLabel.textColor = [UIColor lightGrayColor];
[self addSubview:_placeholderLabel];
// Add text changed notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
}
return self;
}
- (void)setPlaceholder:(NSString *)placeholder {
_placeholderLabel.text = placeholder;
}
- (NSString*)placeholder {
return _placeholderLabel.text;
}
#pragma mark UITextViewTextDidChangeNotification
- (void)textChanged:(NSNotification *)notification {
_placeholderLabel.hidden = ([self.text lenght] == 0);
}
@end
看一下UTPlaceholderTextView。
这是UITextView的一个方便的子类,它支持类似于UITextField的占位符。主要特点:
不使用子视图 不重写drawRect: 占位符的长度可以是任意的,并以与通常文本相同的方式呈现
让我们简单点
创建一个UILabel并把它放在你的文本视图上(给文本作为占位符-设置颜色为灰色-你可以在你的xib中做这一切) 现在在头文件中声明UILabel和textviewDelegate 现在你可以简单地隐藏标签,当你点击textview
完整代码如下
头
@interface ViewController :UIViewController<UITextViewDelegate>{
}
@property (nonatomic,strong) IBOutlet UILabel *PlceHolder_label;
@property (nonatomic,strong) IBOutlet UITextView *TextView;
@end
实现
@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
别忘了连接textView和UILabel文件所有者从xib