- Github上看了几个textView添加Placeholder的方法,有几种方式都会出现textView添加Placeholder位置偏移的情况。实现功能我一向觉得能用最简单最清晰易懂的思路解决就是最棒的方式,提供看到的几种思路,一种是利用runtime添加label的分类,还有一种是添加PlaceholderLabel后各种回调通知,我都觉得太冗余了,现将我最认同最便捷的2种方式,记录一下。
本文仅做记录,参考了[VV木公子] (http://www.jianshu.com/p/9edb8be75e0b)
- 添加label,监听textView的输入。
#import"RedViewController.h"
#define ScreenWidth [[UIScreen mainScreen]bounds].size.width
@interfaceRedViewController()
@property(nonatomic,weak)UITextView*textView;
@property(nonatomic,weak)UILabel*placeHolder;
@end
@implementationRedViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self viewConfig];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewConfig
{
UITextView*textView = [[UITextViewalloc]initWithFrame:CGRectMake(10,74,ScreenWidth-2*10,200)];
textView.frame=CGRectMake(10,74,ScreenWidth-2*10,200);
[self.view addSubview:textView];
self.textView= textView;
textView.contentInset=UIEdgeInsetsMake(-64,0,0,0);
textView.font= [UIFontsystemFontOfSize:14];
textView.delegate=self;
[self setupPlaceHolder];
//在弹出的键盘上面加一个view来放置退出键盘的Done按钮
UIToolbar* topView = [[UIToolbar alloc]initWithFrame:CGRectMake(0,0,ScreenWidth,30)];
[topView setBarStyle:UIBarStyleDefault];
UIBarButtonItem* btnSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpacetarget:selfaction:nil];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc]initWithTitle:@"完成"style:UIBarButtonItemStyleDonetarget:selfaction:@selector(dismissKeyBoard)];
NSArray* buttonsArray = [NSArray arrayWithObjects:btnSpace, doneButton,nil];
[topView setItems:buttonsArray];
[textView setInputAccessoryView:topView];
}
//给textView添加一个UILabel子控件
- (void)setupPlaceHolder
{
UILabel*placeHolder = [[UILabel alloc]initWithFrame:CGRectMake(5,0,200,30)];
self.placeHolder= placeHolder;
placeHolder.text=@"sai is so handsome";
placeHolder.font= [UIFontsystemFontOfSize:12];
placeHolder.textColor= [UIColorlightGrayColor];
placeHolder.numberOfLines=0;
placeHolder.contentMode=UIViewContentModeTop;
[self.textView addSubview:placeHolder];
}
#pragma mark - UITextViewDelegate
- (void)textViewDidChange:(UITextView*)textView
{
if(!textView.text.length) {
self.placeHolder.alpha=1;
}else{
self.placeHolder.alpha=0;
}
}
//关闭键盘
-(void) dismissKeyBoard{
//[self.textView resignFirstResponder];
[self.view endEditing:YES];
}
@end
2、通过运行时,我们发现,UITextView的内部有一个名为“_placeHolderLabel”的私有成员变量。大家知道,Objective-C中没有绝对的私有变量,因为我们可以通过KVC来访问私有变量。虽然苹果官方没有给我们开发者提供类似于占位符的属性,但是通过运行时,我们遍历出了一个placeHolderLabel的私有变量这种方法简单易懂,代码量少,非常聪明 ,哈哈。
#import "GreenViewController.h"
#import <objc/runtime.h>
#import <objc/message.h>
#define ScreenWidth [[UIScreen mainScreen]bounds].size.width
@interface GreenViewController ()
@end
@implementation GreenViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 通过运行时,发现UITextView有一个叫做“_placeHolderLabel”的私有变量
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([UITextView class], &count);
for (int i = 0; i < count; i++) {
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *objcName = [NSString stringWithUTF8String:name];
NSLog(@"%d : %@",i,objcName);
}
[self setupTextView];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setupTextView
{
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 100, [UIScreen mainScreen].bounds.size.width-20, 100)];
[textView setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:textView];
// _placeholderLabel
UILabel *placeHolderLabel = [[UILabel alloc] init];
placeHolderLabel.text = @"请输入内容";
placeHolderLabel.numberOfLines = 0;
placeHolderLabel.textColor = [UIColor lightGrayColor];
[placeHolderLabel sizeToFit];
[textView addSubview:placeHolderLabel];
// same font
textView.font = [UIFont systemFontOfSize:13.f];
placeHolderLabel.font = [UIFont systemFontOfSize:13.f];
self.automaticallyAdjustsScrollViewInsets = NO;
[textView setValue:placeHolderLabel forKey:@"_placeholderLabel"];
}
@end
附加:利用runtime可以获取的列表,用以记录
unsigned int count;
//获取属性列表
objc_property_t *propertyList = class_copyPropertyList([self class], &count);
for (unsigned int i=0; i<count; i++) {
const char *propertyName = property_getName(propertyList[i]);
NSLog(@"property---->%@", [NSString stringWithUTF8String:propertyName]);
}
//获取方法列表
Method *methodList = class_copyMethodList([self class], &count);
for (unsigned int i; i<count; i++) {
Method method = methodList[i];
NSLog(@"method---->%@", NSStringFromSelector(method_getName(method)));
}
//获取成员变量列表
Ivar *ivarList = class_copyIvarList([self class], &count);
for (unsigned int i; i<count; i++) {
Ivar myIvar = ivarList[i];
const char *ivarName = ivar_getName(myIvar);
NSLog(@"Ivar---->%@", [NSString stringWithUTF8String:ivarName]);
}
//获取协议列表
__unsafe_unretained Protocol **protocolList = class_copyProtocolList([self class], &count);
for (unsigned int i; i<count; i++) {
Protocol *myProtocal = protocolList[i];
const char *protocolName = protocol_getName(myProtocal);
NSLog(@"protocol---->%@", [NSString stringWithUTF8String:protocolName]);
}
网友评论