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

如何做到这一点?


当前回答

在看完所有答案后,我意识到我需要一些简单的,同时可重用的东西,这样我就可以在我的项目中为所有uitextview添加相同的功能。最后我得到了以下代码:

extension UITextView {

// MARK: TextView PlaceHolderLabel Setup

func createPlaceHolderLabel(with text: String) {
    let lbl = UILabel()
    self.addSubview(lbl)

// Add your constraints here

    lbl.text = text
    lbl.textColor = .lightGray
}

// My Textview contains only one UILabel, and for my use case the below code works, tweak it according to your use case

// Lastly two methods to toggle between show and hide the placeholder label

func hidePlaceHolderLabel() {
    guard let lbl = self.subviews.first(where: { $0 is UILabel }) else { return }
    lbl.isHidden = true
}

func showPlaceHolderLabel() {
    guard let lbl = self.subviews.first(where: { $0 is UILabel }) else { return }
    lbl.isHidden = false
}

}

当UILabel作为子视图添加到UITextView时,textView游标位置和UILabel位置将不匹配,因此在占位符文本之前留下一个空间

class ViewController: UIViewController, UITextViewDelegate {
    var textView: UITextView!

override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(textView)
    // Also setup textView constraints as per your need
    // Add placeholder to your textView
    // Leave one space before placeholder string
    textView.createPlaceHolderLabel(with: " Address")
    textView.delegate = self
}

然后在textViewdidChange方法中添加以下代码

func textViewDidChange(_ textView: UITextView) {
    if textView.text.isEmpty {
        textView.showPlaceHolderLabel()
    } else {
        textView.hidePlaceHolderLabel()
    }
}

它可以在所有uitextview中重用。

其他回答

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

在textview上放一个标签。

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

你可以看看我的子类。还包括一个演示项目。

我刚刚发现,在iOS 10中,你现在可以将UITextView转换为方法的UITextField,并在方法中设置占位符。刚试过,它不需要子类化UITextView就能工作。

下面是一个对我有用的例子:

-(void)customizeTextField:(UITextField *)textField placeholder:(NSString *)pText withColor:(UIColor *)pTextColor{

        textField.attributedPlaceholder = [[NSAttributedString alloc]
                                          initWithString:pText
                                          attributes:@{NSForegroundColorAttributeName:pTextColor}];
    }

为了将它用于UITextView,你只需要将它传递给方法,使用像这样的类型转换:

[self customizeTextField:(UITextField*)_myTextView placeholder:@"Placeholder" withColor:[UIColor blackColor]];

注:经过测试,我发现这个解决方案在iOS9上也很好。但是会在iOS8.x上导致崩溃

你可以在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与占位符支持。斯威夫特4.2 https://gist.github.com/hlung/c5dda3a0c2087e5ae6c1fce8822c4713

一个支持占位符文本的UITextView子类。它使用另一个 UILabel显示占位符,当文本为空时显示。