我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
当前回答
你可以在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
其他回答
你可以在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
一个更简单的方法是创建一个次要的UITextView,它具有与原始文本视图相同的所有属性,除了不同的textColor,并带有约束以确保它们保持对齐。然后当任何字符进入主文本视图时,隐藏克隆文本视图,否则显示带有一些文本的克隆文本视图。
这可以通过几种方式实现,但相对简单的方法是子类化UITextView并将所有这些逻辑保留在子类中。
所以,子类UITextView并允许它惰性地创建它的占位符视图
接口文件:
@interface FOOTextView : UITextView <UITextViewDelegate>
@property (nonatomic, copy) NSString *placeholderText;
- (void)checkPlaceholder;
@end
实现文件:
#import "FOOTextView.h"
@interface FOOTextView ()
@property (nonatomic, strong) UITextView *placeholderTextView;
@end
@implementation FOOTextView
- (void)checkPlaceholder {
// Hide the placeholder text view if we've got any text
self.placeholderTextView.hidden = (self.text.length > 0 || self.attributedText.length > 0);
}
- (void)setPlaceholderText:(NSString *)placeholderText {
_placeholderText = [placeholderText copy];
// Setup the placeholder text view if we haven't already
[self setupPlaceholderTextView];
// Apply the placeholder text to the placeholder text view
self.placeholderTextView.text = placeholderText;
}
- (void)setupPlaceholderTextView {
if (!self.placeholderTextView) {
// Setup the place holder text view, duplicating our visual setup
self.placeholderTextView = [[UITextView alloc] initWithFrame:CGRectZero];
self.placeholderTextView.translatesAutoresizingMaskIntoConstraints = NO;
self.placeholderTextView.textColor = self.placeholderTextColor ? self.placeholderTextColor : [UIColor colorWithRed:199.f/255.f green:199.f/255.f blue:205.f/255.f alpha:1.f];
self.placeholderTextView.userInteractionEnabled = NO;
self.placeholderTextView.font = self.font;
self.placeholderTextView.textAlignment = self.textAlignment;
self.placeholderTextView.backgroundColor = self.backgroundColor;
self.placeholderTextView.editable = NO;
// Our background color must be clear for the placeholder text view to show through
self.backgroundColor = [UIColor clearColor];
// Insert the placeholder text view into our superview, below ourself so it shows through
[self.superview insertSubview:self.placeholderTextView belowSubview:self];
// Setup constraints to ensure the placeholder text view stays aligned with us
NSLayoutConstraint *constraintCenterX = [NSLayoutConstraint constraintWithItem:self.placeholderTextView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0.f];
NSLayoutConstraint *constraintCenterY = [NSLayoutConstraint constraintWithItem:self.placeholderTextView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.f constant:0.f];
NSLayoutConstraint *constraintWidth = [NSLayoutConstraint constraintWithItem:self.placeholderTextView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:1.f constant:0.f];
NSLayoutConstraint *constraintHeight = [NSLayoutConstraint constraintWithItem:self.placeholderTextView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.f constant:0.f];
NSArray *constraints = @[constraintCenterX, constraintCenterY, constraintWidth, constraintHeight];
[self.superview addConstraints:constraints];
}
}
- (void)setPlaceholderTextColor:(UIColor *)placeholderTextColor {
_placeholderTextColor = placeholderTextColor;
self.placeholderTextView.textColor = _placeholderTextColor;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor {
// We don't want a background color ourselves, instead we want our placeholder text view to have the desired background color
[self.placeholderTextView setBackgroundColor:backgroundColor];
}
- (void)removeFromSuperview {
// Ensure we also remove our placeholder text view
[self.placeholderTextView removeFromSuperview];
self.placeholderTextView = nil;
[super removeFromSuperview];
}
#pragma mark - Text View Delegation
- (void)textViewDidChange:(UITextView *)textView {
[self checkPlaceholder];
}
@end
使用上面的类,如果你设置了一个FOOTextView的委托实例到它自己,一切都将开箱工作:
FOOTextView *myTextView = ...
myTextView.placeholderText = @"What's on your mind?";
myTextView.placeholderTextColor = [UIColor lightGrayColor];
myTextView.delegate = myTextView;
如果你想另一个对象接管作为委托,那么你只需要在textViewDidChange: delegate方法中调用文本视图的checkPlaceholder方法,例如;
FOOTextView *myTextView = ...
myTextView.placeholderText = @"What's on your mind?";
myTextView.placeholderTextColor = [UIColor lightGrayColor];
myTextView.delegate = self;
self.myTextView = myTextView;
- (void)textViewDidChange:(UITextView *)textView {
// Call the checkPlaceholder method to update the visuals
[self.myTextView checkPlaceholder];
}
在UITextView中创建占位符是不可能的,但是你可以通过这个生成类似占位符的效果。
- (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];
}
}
或者你可以添加标签在textview就像
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];
并设置
- (void)textViewDidEndEditing:(UITextView *)theTextView
{
if (![textView hasText]) {
lbl.hidden = NO;
}
}
- (void) textViewDidChange:(UITextView *)textView
{
if(![textView hasText]) {
lbl.hidden = NO;
}
else{
lbl.hidden = YES;
}
}
我对发布的任何解决方案都不太满意,因为它们有点重。向视图中添加视图并不理想(尤其是在drawRect:)。它们都有漏洞,这也是不可接受的。
这是我的解决方案: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/10/11:它现在是文档化的,并支持在接口生成器中使用。
更新11/24/13:指向新的回购。
- (void)viewDidLoad {
[super viewDidLoad];
self.textViewEmpty = YES;
// Text view
self.textView = [[UITextView alloc] init];
self.textView.translatesAutoresizingMaskIntoConstraints = NO; // For AutoLayout
self.textView.delegate = self;
self.textView.textColor = [UIColor grayColor];
self.textView.text = @"Placeholder";
// Add subview and constraints
}
#pragma mark - UITextView
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
if (self.isTextViewEmpty) {
textView.textColor = [UIColor blackColor];
textView.text = @"";
}
return YES;
}
- (void)textViewDidChange:(UITextView *)textView {
if (textView.text.length > 0) {
self.textViewEmpty = NO;
} else {
self.textViewEmpty = YES;
}
}
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
if (self.isTextViewEmpty) {
textView.textColor = [UIColor lightGrayColor];
textView.text = placeholderText;
}
return YES;
}