我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
当前回答
我刚刚发现,在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上导致崩溃
其他回答
我遵循了这个链接的代码。只有7个简单的步骤。它添加了一个UILabel的textView和隐藏/显示标签时,文本输入或从textView通过textView的textViewDidChangeSelection(_ textView: UITextView)委托方法。我将步骤放在代码上方的注释中。
// 1. make sure to include the UITextViewDelegate
class YourClass: UITextViewDelegate {
@IBOutlet weak var textView : UITextView!
// 2. create placeholder textLabel
let placeHolderTextLabel: UILabel = {
let placeholderLabel = UILabel()
placeholderLabel.text = "Placeholder text..."
placeholderLabel.sizeToFit()
placeholderLabel.textColor = UIColor.lightGray
return placeholderLabel
}()
override func viewDidLoad() {
super.viewDidLoad()
// 3. set textView delegate
textView.delegate = self
configurePlaceholderTextLabel()
}
func configurePlaceholderTextLabel() {
// 4. add placeholder label to textView, set it's frame and font
textView.addSubview(placeHolderTextLabel)
placeHolderTextLabel.frame.origin = CGPoint(x: 5, y: (textView.font?.pointSize)! / 2)
placeHolderTextLabel.font = UIFont.systemFont(ofSize: (textView.font?.pointSize)!)
// 5. decide wether the placeHolderTextLabel is hidden or not depending on if there is or isn't text inside the textView
placeHolderTextLabel.isHidden = !textView.text.isEmpty
}
// 6. implement textView delegate method to update the placeHolderTextLabel when the text is changed
func textViewDidChangeSelection(_ textView: UITextView) {
// 7. decide wether the placeHolderTextLabel is hidden or not depending on if there is or isn't text inside the textView when text in textView is changed
placeHolderTextLabel.isHidden = !textView.text.isEmpty
}
}
我能够做添加一个“占位符”到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;
我猜这不是一个真正的占位符,因为你必须在写之前删除文本,但如果你想要一些更简单的东西,它可能会有帮助。
我对发布的任何解决方案都不太满意,因为它们有点重。向视图中添加视图并不理想(尤其是在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:指向新的回购。
在UITextView PlaceholderTextView中支持图标属性占位符的简单类
@IBOutlet weak var tvMessage: PlaceholderTextView!
// TODO: - Create Icon Text Attachment
let icon: NSTextAttachment = NSTextAttachment()
icon.image = UIImage(named: "paper-plane")
let iconString = NSMutableAttributedString(attributedString: NSAttributedString(attachment: icon))
tvMessage.icon = icon
// TODO: - Attributes
let textColor = UIColor.gray
let lightFont = UIFont(name: "Helvetica-Light", size: tvMessage.font!.pointSize)
let italicFont = UIFont(name: "Helvetica-LightOblique", size: tvMessage.font!.pointSize)
// TODO: - Placeholder Attributed String
let message = NSAttributedString(string: " " + "Personal Message", attributes: [ NSFontAttributeName: lightFont!, NSForegroundColorAttributeName: textColor])
iconString.append(message)
// TODO: - Italic Placeholder Part
let option = NSAttributedString(string: " " + "Optional", attributes: [ NSFontAttributeName: italicFont!, NSForegroundColorAttributeName: textColor])
iconString.append(option)
tvMessage.attributedPlaceHolder = iconString
tvMessage.layoutSubviews()
在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;
}
}