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

如何做到这一点?


当前回答

简单的Swift 3解决方案

添加UITextViewDelegate到类中

设置你的textview .delegate = self

创建placeholderLabel和位置它在你的textview

现在动画placeholderLabel。alpha在textViewDidChange:

  func textViewDidChange(_ textView: UITextView) {
    let newAlpha: CGFloat = textView.text.isEmpty ? 1 : 0
    if placeholderLabel.alpha != newAlpha {
      UIView.animate(withDuration: 0.3) {
        self.placeholderLabel.alpha = newAlpha
      }
    }
  }

你可能不得不使用placeholderLabel位置来设置它,但这应该不会太难

其他回答

还有一个简单的答案,使用CATextLayer。

添加CATextLayer到UITextView的层。 使用UITextViewDelegate方法,简单地改变CATextLayer的颜色。

func txtViewPlaceholder() {
    let textlayer = CATextLayer()

    textlayer.frame = CGRect(x: 5, y: 5, width: 200, height: 18)
    textlayer.contentsScale = UIScreen.main.scale
    textlayer.fontSize = 12
    textlayer.alignmentMode = kCAAlignmentLeft
    textlayer.string = "Enter here"
    textlayer.isWrapped = true
    textlayer.name = "placeholder"
    textlayer.backgroundColor = UIColor.white.cgColor
    textlayer.foregroundColor = UIColor.black.cgColor

    yourTxtVw.layer.insertSublayer(textlayer, at: 0)
}

func removeAddPlaceholder(remove: Bool, textView: UITextView) {
    for layers in textView.layer.sublayers! where layers.name == "placeholder" {
        
        if remove {
            (layers as! CATextLayer).foregroundColor = UIColor.white.cgColor
        } else {
            (layers as! CATextLayer).foregroundColor = UIColor.black.cgColor
        }
        
    }
}


extension YourViewController : UITextViewDelegate {

    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
    
        removeAddPlaceholder(remove: true, textView: textView)
    
        return true
    }

    func textViewDidEndEditing(_ textView: UITextView) {
    
        if textView.text.count <= 0 {
            removeAddPlaceholder(remove: false, textView: textView)
        }
    }

}

这里有一个更简单的解决方案,它的行为完全像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语句中的第二个检查是针对没有输入任何内容且用户按下退格键的情况)

只需要将你的类设置为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;
}

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

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

在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;
 }  
}

我创建了一个实例变量来检查是否显示占位符:

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

在viewDidLoad上设置:

[self setPlaceHolder]; 

下面是它的作用:

- (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
}

我还创建了一个按钮来退出键盘。您不必这样做,但这里很酷的事情是,如果没有输入任何内容,占位符将再次显示

- (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];
    }       
}