UITextView で Placeholder を使う
UITextField には Placeholder が用意されているけど、UITextView にはないみたい。
以下の stackoverflow にそのものズバリな回答があったのでこれをそのまま使った。
ios - Placeholder in UITextView - Stack Overflow
http://stackoverflow.com/questions/1328638/placeholder-in-uitextview
UITextView クラスを継承して Placeholder 機能を追加した UIPlaceHolderTextView クラスを作成する。使う場合には以下のようにplaceholder
プロパティに文字列を設定してあげればよい。文字色を変えたければplaceholderColor
プロパティに UIColor を設定する。
placeHolderTextView.placeholder = @"タップして内容を入力してください"; placeHolderTextView.placeholderColor = [UIColor lightGrayColor]; // デフォルトは lightGrayColor
こんなかんじになる。
UIPlaceHolderTextView.h
#import <UIKit/UIKit.h> @interface UIPlaceHolderTextView : UITextView @property(nonatomic, strong) NSString *placeholder; @property(nonatomic, strong) UIColor *placeholderColor; - (void)textChanged:(NSNotification *)notification; @end
UIPlaceHolderTextView.m
#import "UIPlaceHolderTextView.h" @interface UIPlaceHolderTextView () @property(nonatomic, strong) UILabel *placeHolderLabel; @end @implementation UIPlaceHolderTextView CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25; - (void)awakeFromNib { [super awakeFromNib]; // Use Interface Builder User Defined Runtime Attributes to set // placeholder and placeholderColor in Interface Builder. if (!self.placeholder) { [self setPlaceholder:@""]; } if (!self.placeholderColor) { [self setPlaceholderColor:[UIColor lightGrayColor]]; } [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil]; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code [self setPlaceholder:@""]; [self setPlaceholderColor:[UIColor lightGrayColor]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil]; } return self; } - (void)textChanged:(NSNotification *)notification { if ([[self placeholder] length] == 0) { return; } [UIView animateWithDuration:UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION animations:^{ if([[self text] length] == 0) { [[self viewWithTag:999] setAlpha:1]; } else { [[self viewWithTag:999] setAlpha:0]; } }]; } - (void)setText:(NSString *)text { [super setText:text]; [self textChanged:nil]; } - (void)drawRect:(CGRect)rect { if ([[self placeholder] length] > 0) { if (_placeHolderLabel == nil) { _placeHolderLabel = [[UILabel alloc] initWithFrame:CGRectMake(8,8,self.bounds.size.width - 16,0)]; _placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping; _placeHolderLabel.numberOfLines = 0; _placeHolderLabel.font = self.font; _placeHolderLabel.backgroundColor = [UIColor clearColor]; _placeHolderLabel.textColor = self.placeholderColor; _placeHolderLabel.alpha = 0; _placeHolderLabel.tag = 999; [self addSubview:_placeHolderLabel]; } _placeHolderLabel.text = self.placeholder; [_placeHolderLabel sizeToFit]; [self sendSubviewToBack:_placeHolderLabel]; } if ([[self text] length] == 0 && [[self placeholder] length] > 0) { [[self viewWithTag:999] setAlpha:1]; } [super drawRect:rect]; } @end
やってることは
- Placeholder を UILabel で作成し、UITextView の subview に追加
- NSNotificationCenter に UITextView の
UITextViewTextDidBeginEditingNotification
を登録 - UITextView のテキストに変更があったら Placeholder の alpha 値を変更して表示、非表示を切り替え
という流れ。
以下は、UIPlaceHolderTextView を使う例。nb や sb は使わずコードだけで実装。
ついでに TextView で入力後にキーボードが隠れるように AccessoryView に「完了」ボタンを追加している。
#import "SampleTextViewController.h" #import "UIPlaceHolderTextView.h" @interface SampleTextViewController () @property(nonatomic, strong) UIPlaceHolderTextView *myPlaceHolderTextView; @end @implementation SampleTextViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor grayColor]; // ツールバー作成 UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)]; UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithTitle:@"完了" style:UIBarButtonItemStylePlain target:self action:@selector(performDoneButtonAction)]; // 「完了」ボタンを右寄せにしたいので左側に可変間隔スペーサーを挟む UIBarButtonItem *flexibleSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; toolBar.items = @[flexibleSpacer, btn]; // PlaceHolder を拡張した TextView 作成 const float TEXT_VIEW_WIDTH_SPACE = 40; self.myPlaceHolderTextView = [[UIPlaceHolderTextView alloc] init]; self.myPlaceHolderTextView.placeholder = @"タップして内容を入力してください"; self.myPlaceHolderTextView.frame = CGRectMake(TEXT_VIEW_WIDTH_SPACE / 2, 100, self.view.bounds.size.width - TEXT_VIEW_WIDTH_SPACE, 200); // AccessoryView にツールバーを追加する self.myPlaceHolderTextView.inputAccessoryView = toolBar; [self.view addSubview:self.myPlaceHolderTextView]; } - (void)performDoneButtonAction { // キーボードを隠す [self.myPlaceHolderTextView resignFirstResponder]; } @end