我的应用程序使用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上导致崩溃
其他回答
我找到了自己的解决方案
- (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;
}
另一个解决方案
import UIKit
protocol PlaceholderTextViewDelegate: class {
func placeholderTextViewDidChangeText(_ text: String)
func placeholderTextViewDidEndEditing(_ text: String)
}
final class PlaceholderTextView: UITextView {
weak var notifier: PlaceholderTextViewDelegate?
var ignoreEnterAction: Bool = true
var placeholder: String? {
didSet {
text = placeholder
selectedRange = NSRange(location: 0, length: 0)
}
}
var placeholderColor = UIColor.lightGray {
didSet {
if text == placeholder {
textColor = placeholderColor
}
}
}
var normalTextColor = UIColor.lightGray
var placeholderFont = UIFont.sfProRegular(28)
fileprivate var placeholderLabel: UILabel?
// MARK: - LifeCycle
override var text: String? {
didSet {
if text == placeholder {
textColor = placeholderColor
} else {
textColor = normalTextColor
}
}
}
init() {
super.init(frame: CGRect.zero, textContainer: nil)
awakeFromNib()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
self.delegate = self
}
}
extension PlaceholderTextView: UITextViewDelegate {
// MARK: - UITextViewDelegate
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "" && textView.text == placeholder {
return false
}
if let placeholder = placeholder,
textView.text == placeholder,
range.location <= placeholder.count {
textView.text = ""
}
if ignoreEnterAction && text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
func textViewDidChange(_ textView: UITextView) {
if let placeholder = placeholder {
textView.text = textView.text.replacingOccurrences(of: placeholder, with: "")
}
if let placeholder = placeholder,
text?.isEmpty == true {
text = placeholder
textColor = placeholderColor
selectedRange = NSRange(location: 0, length: 0)
} else {
textColor = normalTextColor
}
notifier?.placeholderTextViewDidChangeText(textView.text)
}
func textViewDidChangeSelection(_ textView: UITextView) {
if let placeholder = placeholder,
text == placeholder {
selectedRange = NSRange(location: 0, length: 0)
}
}
func textViewDidEndEditing(_ textView: UITextView) {
notifier?.placeholderTextViewDidEndEditing(textView.text)
if let placeholder = placeholder,
text?.isEmpty == true {
text = placeholder
textColor = placeholderColor
selectedRange = NSRange(location: 0, length: 0)
} else {
textColor = normalTextColor
}
}
}
结果:
简单的方法,使用以下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
{
}
这里还有另一种方法,它复制了UITextField占位符的轻微缩进:
将UITextField拖到UITextView的右边,这样它们的左上角就对齐了。将占位符文本添加到文本字段。
在viewDidLoad中添加:
[tView setDelegate:self];
tView.contentInset = UIEdgeInsetsMake(-8,-8,0,0);
tView.backgroundColor = [UIColor clearColor];
然后添加:
- (void)textViewDidChange:(UITextView *)textView {
if (textView.text.length == 0) {
textView.backgroundColor = [UIColor clearColor];
} else {
textView.backgroundColor = [UIColor whiteColor];
}
}
你能做的是在文本属性中设置文本视图的初始值,并将textColor更改为[UIColor grayColor]或类似的东西。然后,每当文本视图变为可编辑时,清除文本并显示游标,如果文本字段再次为空,则将占位符文本放回。根据需要将颜色更改为[UIColor blackColor]。
它与UITextField中的占位符功能不完全相同,但很接近。