我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
当前回答
- (BOOL) textViewShouldBeginEditing:(UITextView *)textView
{
//NSLog(@"textViewShouldBeginEditing");
if( [tvComment.text isEqualToString:@"Comment"] && [tvComment.textColor isEqual:[UIColor lightGrayColor]] ){
tvComment.text = @"";
tvComment.textColor = [UIColor blackColor];
}
return YES;
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification{
//NSLog(@"keyboardWillBeHidden");
//Manage comment field placeholdertext
if(tvComment.text.length == 0){
tvComment.textColor = [UIColor lightGrayColor];
tvComment.text = @"Comment";
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
tvComment.textColor = [UIColor lightGrayColor];
}
TVComment是包含问题中的textView的属性。这样就可以了。
其他回答
下面是swift 3.1的代码
原始代码由杰森乔治在第一个答案。
不要忘记设置你的自定义类的TextView在接口生成器UIPlaceHolderTextView,然后设置占位符和占位符属性。
import UIKit
@IBDesignable
class UIPlaceHolderTextView: UITextView {
@IBInspectable var placeholder: String = ""
@IBInspectable var placeholderColor: UIColor = UIColor.lightGray
private let uiPlaceholderTextChangedAnimationDuration: Double = 0.05
private let defaultTagValue = 999
private var placeHolderLabel: UILabel?
override func awakeFromNib() {
super.awakeFromNib()
NotificationCenter.default.addObserver(
self,
selector: #selector(textChanged),
name: NSNotification.Name.UITextViewTextDidChange,
object: nil
)
}
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
NotificationCenter.default.addObserver(
self,
selector: #selector(textChanged),
name: NSNotification.Name.UITextViewTextDidChange,
object: nil
)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
NotificationCenter.default.addObserver(
self,
selector: #selector(textChanged),
name: NSNotification.Name.UITextViewTextDidChange,
object: nil
)
}
deinit {
NotificationCenter.default.removeObserver(
self,
name: NSNotification.Name.UITextViewTextDidChange,
object: nil
)
}
@objc private func textChanged() {
guard !placeholder.isEmpty else {
return
}
UIView.animate(withDuration: uiPlaceholderTextChangedAnimationDuration) {
if self.text.isEmpty {
self.viewWithTag(self.defaultTagValue)?.alpha = CGFloat(1.0)
}
else {
self.viewWithTag(self.defaultTagValue)?.alpha = CGFloat(0.0)
}
}
}
override var text: String! {
didSet{
super.text = text
textChanged()
}
}
override func draw(_ rect: CGRect) {
if !placeholder.isEmpty {
if placeHolderLabel == nil {
placeHolderLabel = UILabel.init(frame: CGRect(x: 0, y: 8, width: bounds.size.width - 16, height: 0))
placeHolderLabel!.lineBreakMode = .byWordWrapping
placeHolderLabel!.numberOfLines = 0
placeHolderLabel!.font = font
placeHolderLabel!.backgroundColor = UIColor.clear
placeHolderLabel!.textColor = placeholderColor
placeHolderLabel!.alpha = 0
placeHolderLabel!.tag = defaultTagValue
self.addSubview(placeHolderLabel!)
}
placeHolderLabel!.text = placeholder
placeHolderLabel!.sizeToFit()
self.sendSubview(toBack: placeHolderLabel!)
if text.isEmpty && !placeholder.isEmpty {
viewWithTag(defaultTagValue)?.alpha = 1.0
}
}
super.draw(rect)
}
}
更简单,并且仍然考虑到用户在某些时候输入的一些文本
BOOL placeHolderTextVisible;
在viewDidLoad上,设置它为YES(或DidMoveToSuperview,或awakeFromNib)
然后,在 - (BOOL) textView:(UITextView*)textView shouldBeginEditing
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView;
{
if (placeHolderTextVisible) {
placeHolderTextVisible = NO;
textView.text = @"";
}
return YES;
}
这里有一个简单而聪明的方法来获得完美的行为。
让我们借用UITextField中的占位符。
Set up a textField and set its text transparent. self.placeholderTextField = [[UITextField alloc] init]; /* adjust the frame to fit it in the first line of your textView */ self.placeholderTextField.frame = CGRectMake(0.0, 0.0, yourTextView.width, 30.0); self.placeholderTextField.textColor = [UIColor clearColor]; self.placeholderTextField.userInteractionEnabled = NO; self.placeholderTextField.font = yourTextView.font; self.placeholderTextField.placeholder = @"sample placeholder"; [yourTextView addSubview:self.placeholderTextField]; Set textView's delegate and synchronize the textField and textView. yourTextView.delegate = self; then - (void)textViewDidChange:(UITextView *)textView { self.placeholderTextField.text = textView.text; } That's all.
你也可以创建一个新的类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];
}
}
你可以在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