我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
当前回答
基于这里已经给出的一些很好的建议,我能够将以下轻量级的、与接口生成器兼容的UITextView子类组合在一起,它是:
包括可配置的占位符文本,样式就像UITextField一样。 不需要任何额外的子视图或约束。 不需要来自ViewController的任何委托或其他行为。 不需要任何通知。 保持该文本与查看字段的文本属性的任何外部类完全分离。
欢迎提出改进建议。
编辑1:更新为重置占位符格式,如果实际文本以编程方式设置。
编辑2:现在可以以编程方式检索占位符文本颜色。
斯威夫特v5:
import UIKit
@IBDesignable class TextViewWithPlaceholder: UITextView {
override var text: String! { // Ensures that the placeholder text is never returned as the field's text
get {
if showingPlaceholder {
return "" // When showing the placeholder, there's no real text to return
} else { return super.text }
}
set {
if showingPlaceholder {
removePlaceholderFormatting() // If the placeholder text is what's being changed, it's no longer the placeholder
}
super.text = newValue
}
}
@IBInspectable var placeholderText: String = ""
@IBInspectable var placeholderTextColor: UIColor = .placeholderText
private var showingPlaceholder: Bool = true // Keeps track of whether the field is currently showing a placeholder
override func didMoveToWindow() {
super.didMoveToWindow()
if text.isEmpty {
showPlaceholderText() // Load up the placeholder text when first appearing, but not if coming back to a view where text was already entered
}
}
override public func becomeFirstResponder() -> Bool {
// If the current text is the placeholder, remove it
if showingPlaceholder {
text = nil
removePlaceholderFormatting()
}
return super.becomeFirstResponder()
}
override public func resignFirstResponder() -> Bool {
// If there's no text, put the placeholder back
if text.isEmpty {
showPlaceholderText()
}
return super.resignFirstResponder()
}
private func showPlaceholderText() {
text = placeholderText
showingPlaceholder = true
textColor = placeholderTextColor
}
private func removePlaceholderFormatting() {
showingPlaceholder = false
textColor = nil // Put the text back to the default, unmodified color
}
}
其他回答
在h课上
@interface RateCommentViewController : UIViewController<UITextViewDelegate>{IBoutlet UITextview *commentTxtView;}
在。m类
- (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];
}
}
我找到了自己的解决方案
- (void)textViewDidBeginEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:PLACEHOLDER_TEXT])
{
textView.textColor = [UIColor lightGrayColor];
dispatch_async(dispatch_get_main_queue(), ^
{
textView.selectedRange = NSMakeRange(0, 0);
});
}
else
{
textView.textColor = [UIColor blackColor];
}
[textView becomeFirstResponder];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:@""])
{
textView.text = PLACEHOLDER_TEXT;
textView.textColor = [UIColor lightGrayColor];
}
[textView resignFirstResponder];
}
- (BOOL)textView:(UITextView *)textView
shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
if (range.location == 0 && range.length == [[textView text] length] && [text isEqualToString:@""])
{
textView.text = PLACEHOLDER_TEXT;
textView.textColor = [UIColor lightGrayColor];
dispatch_async(dispatch_get_main_queue(), ^
{
textView.selectedRange = NSMakeRange(0, 0);
});
return NO;
}
if ([textView.text isEqualToString:PLACEHOLDER_TEXT])
{
textView.text = @"";
textView.textColor = [UIColor blackColor];
}
return YES;
}
简单的方法,使用以下UITextViewDelegate方法在UITextView中创建占位符文本:
- (void)textViewDidBeginEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:@"placeholder text here..."]) {
textView.text = @"";
textView.textColor = [UIColor blackColor]; //optional
}
[textView becomeFirstResponder];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:@""]) {
textView.text = @"placeholder text here...";
textView.textColor = [UIColor lightGrayColor]; //optional
}
[textView resignFirstResponder];
}
只需要记住在创建时使用准确的文本设置myUITextView即可。
UITextView *myUITextView = [[UITextView alloc] init];
myUITextView.delegate = self;
myUITextView.text = @"placeholder text here...";
myUITextView.textColor = [UIColor lightGrayColor]; //optional
在包含这些方法之前,让父类成为一个UITextViewDelegate。
@interface MyClass () <UITextViewDelegate>
@end
Swift 3.1代码
func textViewDidBeginEditing(_ textView: UITextView)
{
if (textView.text == "placeholder text here..." && textView.textColor == .lightGray)
{
textView.text = ""
textView.textColor = .black
}
textView.becomeFirstResponder() //Optional
}
func textViewDidEndEditing(_ textView: UITextView)
{
if (textView.text == "")
{
textView.text = "placeholder text here..."
textView.textColor = .lightGray
}
textView.resignFirstResponder()
}
只需要记住在创建时使用准确的文本设置myUITextView即可。
let myUITextView = UITextView.init()
myUITextView.delegate = self
myUITextView.text = "placeholder text here..."
myUITextView.textColor = .lightGray
在包含这些方法之前,让父类成为一个UITextViewDelegate。
class MyClass: UITextViewDelegate
{
}
我能够做添加一个“占位符”到UITextView与很多少的代码。这就是我所做的:
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(60, 800, 200, 60)];
textView.text = @"Write characters here...";
textView.textColor=[UIColor grayColor];
textView.font = [UIFont fontWithName:@"Hevlatica" size:15];
textView.delegate=self;
我猜这不是一个真正的占位符,因为你必须在写之前删除文本,但如果你想要一些更简单的东西,它可能会有帮助。
下面是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)
}
}