我的应用程序使用UITextView。现在我想让UITextView有一个占位符,类似于你可以为UITextField设置的占位符。
如何做到这一点?
我的应用程序使用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位置来设置它,但这应该不会太难
其他回答
简单的方法,使用以下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,它具有与原始文本视图相同的所有属性,除了不同的textColor,并带有约束以确保它们保持对齐。然后当任何字符进入主文本视图时,隐藏克隆文本视图,否则显示带有一些文本的克隆文本视图。
这可以通过几种方式实现,但相对简单的方法是子类化UITextView并将所有这些逻辑保留在子类中。
所以,子类UITextView并允许它惰性地创建它的占位符视图
接口文件:
@interface FOOTextView : UITextView <UITextViewDelegate>
@property (nonatomic, copy) NSString *placeholderText;
- (void)checkPlaceholder;
@end
实现文件:
#import "FOOTextView.h"
@interface FOOTextView ()
@property (nonatomic, strong) UITextView *placeholderTextView;
@end
@implementation FOOTextView
- (void)checkPlaceholder {
// Hide the placeholder text view if we've got any text
self.placeholderTextView.hidden = (self.text.length > 0 || self.attributedText.length > 0);
}
- (void)setPlaceholderText:(NSString *)placeholderText {
_placeholderText = [placeholderText copy];
// Setup the placeholder text view if we haven't already
[self setupPlaceholderTextView];
// Apply the placeholder text to the placeholder text view
self.placeholderTextView.text = placeholderText;
}
- (void)setupPlaceholderTextView {
if (!self.placeholderTextView) {
// Setup the place holder text view, duplicating our visual setup
self.placeholderTextView = [[UITextView alloc] initWithFrame:CGRectZero];
self.placeholderTextView.translatesAutoresizingMaskIntoConstraints = NO;
self.placeholderTextView.textColor = self.placeholderTextColor ? self.placeholderTextColor : [UIColor colorWithRed:199.f/255.f green:199.f/255.f blue:205.f/255.f alpha:1.f];
self.placeholderTextView.userInteractionEnabled = NO;
self.placeholderTextView.font = self.font;
self.placeholderTextView.textAlignment = self.textAlignment;
self.placeholderTextView.backgroundColor = self.backgroundColor;
self.placeholderTextView.editable = NO;
// Our background color must be clear for the placeholder text view to show through
self.backgroundColor = [UIColor clearColor];
// Insert the placeholder text view into our superview, below ourself so it shows through
[self.superview insertSubview:self.placeholderTextView belowSubview:self];
// Setup constraints to ensure the placeholder text view stays aligned with us
NSLayoutConstraint *constraintCenterX = [NSLayoutConstraint constraintWithItem:self.placeholderTextView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0.f];
NSLayoutConstraint *constraintCenterY = [NSLayoutConstraint constraintWithItem:self.placeholderTextView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.f constant:0.f];
NSLayoutConstraint *constraintWidth = [NSLayoutConstraint constraintWithItem:self.placeholderTextView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:1.f constant:0.f];
NSLayoutConstraint *constraintHeight = [NSLayoutConstraint constraintWithItem:self.placeholderTextView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.f constant:0.f];
NSArray *constraints = @[constraintCenterX, constraintCenterY, constraintWidth, constraintHeight];
[self.superview addConstraints:constraints];
}
}
- (void)setPlaceholderTextColor:(UIColor *)placeholderTextColor {
_placeholderTextColor = placeholderTextColor;
self.placeholderTextView.textColor = _placeholderTextColor;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor {
// We don't want a background color ourselves, instead we want our placeholder text view to have the desired background color
[self.placeholderTextView setBackgroundColor:backgroundColor];
}
- (void)removeFromSuperview {
// Ensure we also remove our placeholder text view
[self.placeholderTextView removeFromSuperview];
self.placeholderTextView = nil;
[super removeFromSuperview];
}
#pragma mark - Text View Delegation
- (void)textViewDidChange:(UITextView *)textView {
[self checkPlaceholder];
}
@end
使用上面的类,如果你设置了一个FOOTextView的委托实例到它自己,一切都将开箱工作:
FOOTextView *myTextView = ...
myTextView.placeholderText = @"What's on your mind?";
myTextView.placeholderTextColor = [UIColor lightGrayColor];
myTextView.delegate = myTextView;
如果你想另一个对象接管作为委托,那么你只需要在textViewDidChange: delegate方法中调用文本视图的checkPlaceholder方法,例如;
FOOTextView *myTextView = ...
myTextView.placeholderText = @"What's on your mind?";
myTextView.placeholderTextColor = [UIColor lightGrayColor];
myTextView.delegate = self;
self.myTextView = myTextView;
- (void)textViewDidChange:(UITextView *)textView {
// Call the checkPlaceholder method to update the visuals
[self.myTextView checkPlaceholder];
}
让我们简单点
创建一个UILabel并把它放在你的文本视图上(给文本作为占位符-设置颜色为灰色-你可以在你的xib中做这一切) 现在在头文件中声明UILabel和textviewDelegate 现在你可以简单地隐藏标签,当你点击textview
完整代码如下
头
@interface ViewController :UIViewController<UITextViewDelegate>{
}
@property (nonatomic,strong) IBOutlet UILabel *PlceHolder_label;
@property (nonatomic,strong) IBOutlet UITextView *TextView;
@end
实现
@implementation UploadFoodImageViewController
@synthesize PlceHolder_label,TextView;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView{
if([textView isEqual:TextView]){
[PlceHolder_label setHidden:YES];
[self.tabScrlVw setContentOffset:CGPointMake(0,150) animated:YES];
}
return YES;
}
@end
别忘了连接textView和UILabel文件所有者从xib
好吧,我的阴沟有点不同 我创建了一个小班来为你做这件事。
TextViewShader。m文件
#import "TextViewShader.h"
@implementation TextViewShader
-(id)initWithShadedTextView:(NSString *)text textViewToShade:(UITextView *)textview {
self = [super initWithFrame:textview.frame];
if (self) {
if (shadeLabel==nil)
{
shadeLabel= [[UILabel alloc]initWithFrame:CGRectMake(10, 0, textview.frame.size.width, 30)];
}
shadeLabel.text =text;// @"Enter Your Support Request";
shadeLabel.textColor = [UIColor lightGrayColor];
[textview setDelegate: self];
[textview addSubview:shadeLabel];
}
return self;
}
-(void)textViewDidChange:(UITextView *)textView{
if (textView.text.length==0)
{
shadeLabel.hidden=false;
}
else
{
shadeLabel.hidden=true;
}
}
@end
TextViewShader.h文件
#import <UIKit/UIKit.h>
@interface TextViewShader : UIView<UITextViewDelegate>{
UILabel *shadeLabel;
}
-(id)initWithShadedTextView:(NSString *)text textViewToShade:(UITextView *)textview ;
@end
这是简单的一行代码使用(不要忘记添加#import "TextViewShader.h")
TextViewShader* shader = [[TextViewShader alloc]initWithShadedTextView:@"Enter Your Support Request" textViewToShade: youruitextviewToshade];
玩得开心!
I know there are already a lot of answers to this one, but I didn't really find any of them sufficient (at least in Swift). I needed the "placeholder" functionality of the UITextField in my UITextView (I wanted the exact behavior, including text display attributes, animations, etc, and didn't want to have to maintain this over time). I also wanted a solution that provided the same exact border as a UITextField (not an approximated one that looks sort of like it looks right now, but one that looks exactly like it and will always look exactly like it). So while I was not initially a fan of jamming an extra control into the mix, it seemed that in order to meet my goals I had to use an actual UITextField and let it do the work.
这个解决方案处理定位占位符和保持字体在两个控件之间的同步,以便占位符文本是输入到控件的文本的确切字体和位置(许多其他解决方案没有解决的问题)。
// This class is necessary to support "inset" (required to position placeholder
// appropriately in TextView)
//
class TextField: UITextField
{
var inset: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0);
override func textRectForBounds(bounds: CGRect) -> CGRect
{
return UIEdgeInsetsInsetRect(bounds, inset);
}
override func placeholderRectForBounds(bounds: CGRect) -> CGRect
{
return UIEdgeInsetsInsetRect(bounds, inset);
}
}
// This class implements a UITextView that has a UITextField behind it, where the
// UITextField provides the border and the placeholder text functionality (so that the
// TextView looks and works like a UITextField).
//
class TextView : UITextView, UITextViewDelegate
{
var textField = TextField();
required init?(coder: NSCoder)
{
super.init(coder: coder);
}
override init(frame: CGRect, textContainer: NSTextContainer?)
{
super.init(frame: frame, textContainer: textContainer);
self.delegate = self;
// Create a background TextField with clear (invisible) text and disabled
self.textField.borderStyle = UITextBorderStyle.RoundedRect;
self.textField.textColor = UIColor.clearColor();
self.textField.userInteractionEnabled = false;
// Align the background TextView to where text appears in the TextField, so
// that any placeholder will be in the correct position.
self.textField.contentVerticalAlignment = UIControlContentVerticalAlignment.Top;
self.textField.inset = UIEdgeInsets(
top: self.textContainerInset.top,
left: self.textContainerInset.left + self.textContainer.lineFragmentPadding,
bottom: self.textContainerInset.bottom,
right: self.textContainerInset.right
);
// The background TextField should use the same font (for the placeholder)
self.textField.font = self.font;
self.addSubview(textField);
self.sendSubviewToBack(textField);
}
convenience init()
{
self.init(frame: CGRectZero, textContainer: nil)
}
override var font: UIFont?
{
didSet
{
// Keep the font of the TextView and background textField in sync
self.textField.font = self.font;
}
}
var placeholder: String? = nil
{
didSet
{
self.textField.placeholder = self.placeholder;
}
}
override func layoutSubviews()
{
super.layoutSubviews()
// Do not scroll the background textView
self.textField.frame = CGRectMake(0, self.contentOffset.y, self.frame.width, self.frame.height);
}
// UITextViewDelegate - Note: If you replace delegate, your delegate must call this
func scrollViewDidScroll(scrollView: UIScrollView)
{
// Do not scroll the background textView
self.textField.frame = CGRectMake(0, self.contentOffset.y, self.frame.width, self.frame.height);
}
// UITextViewDelegate - Note: If you replace delegate, your delegate must call this
func textViewDidChange(textView: UITextView)
{
// Updating the text in the background textView will cause the placeholder to
// appear/disappear (including any animations of that behavior - since the
// textView is doing this itself).
self.textField.text = self.text;
}
}