//
// SSTextView.h
// SSToolkit
//
// Created by Sam Soffes on 8/18/10.
// Copyright 2010-2011 Sam Soffes. All rights reserved.
//
/**
UITextView subclass that adds placeholder support like UITextField has.
*/
@interface
SSTextView
: UITextView
/**
The string that is displayed when there is no other text in the text view.
The default value is `nil`.
*/
@property
(
nonatomic
,
retain
)
NSString
*placeholder;
/**
The color of the placeholder.
The default is `[UIColor lightGrayColor]`.
*/
@property
(
nonatomic
,
retain
)
UIColor
*placeholderColor;
@end
//
// SSTextView.m
// SSToolkit
//
// Created by Sam Soffes on 8/18/10.
// Copyright 2010-2011 Sam Soffes. All rights reserved.
//
#import "SSTextView.h"
@interface
SSTextView
()
- (
void
)_initialize;
- (
void
)_updateShouldDrawPlaceholder;
- (
void
)_textChanged:(
NSNotification
*)notification;
@end
@implementation
SSTextView
{
BOOL
_shouldDrawPlaceholder;
}
#pragma mark - Accessors
@synthesize
placeholder = _placeholder;
@synthesize
placeholderColor = _placeholderColor;
- (
void
)setText:(
NSString
*)string {
[
super
setText
:string];
[
self
_updateShouldDrawPlaceholder
];
}
- (
void
)setPlaceholder:(
NSString
*)string {
if
([string
isEqual
:_placeholder]) {
return
;
}
[_placeholder
release
];
_placeholder = [string
retain
];
[
self
_updateShouldDrawPlaceholder
];
}
#pragma mark - NSObject
- (
void
)dealloc {
[[
NSNotificationCenter
defaultCenter
]
removeObserver
:
self
name
:
UITextViewTextDidChangeNotification
object
:
self
];
[_placeholder
release
];
[_placeholderColor
release
];
[
super
dealloc
];
}
#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
(_shouldDrawPlaceholder) {
[_placeholderColor
set
];
[_placeholder
drawInRect
:CGRectMake(
8
.0f
,
8
.0f
,
self
.frame
.size
.width
-
1
6
.0f
,
self
.frame
.size
.height
-
1
6
.0f
)
withFont
:
self
.font
];
}
}
#pragma mark - Private
- (
void
)_initialize {
[[
NSNotificationCenter
defaultCenter
]
addObserver
:
self
selector
:
@selector
(_textChanged:)
name
:
UITextViewTextDidChangeNotification
object
:
self
];
self
.placeholderColor
= [
UIColor
colorWithWhite
:
0
.702f
alpha
:
1
.0f
];
_shouldDrawPlaceholder =
NO
;
}
- (
void
)_updateShouldDrawPlaceholder {
BOOL
prev = _shouldDrawPlaceholder;
_shouldDrawPlaceholder =
self
.placeholder
&&
self
.placeholderColor
&&
self
.text
.length
==
0
;
if
(prev != _shouldDrawPlaceholder) {
[
self
setNeedsDisplay
];
}
}
- (
void
)_textChanged:(
NSNotification
*)notificaiton {
[
self
_updateShouldDrawPlaceholder
];
}
@end
另外一种实现方式。
#import <Foundation/Foundation.h>
@interface
UIPlaceHolderTextView
:
UITextView
{
NSString
*placeholder;
UIColor
*placeholderColor;
@private
UILabel
*placeHolderLabel;
}
@property
(
nonatomic
,
retain
)
UILabel
*placeHolderLabel;
@property
(
nonatomic
,
retain
)
NSString
*placeholder;
@property
(
nonatomic
,
retain
)
UIColor
*placeholderColor;
-(
void
)textChanged:(NSNotification*)notification;
@end
//.m file
#import "UIPlaceHolderTextView.h"
@implementation
UIPlaceHolderTextView
@synthesize
placeHolderLabel;
@synthesize
placeholder;
@synthesize
placeholderColor;
- (
void
)dealloc
{
[[
NSNotificationCenter
defaultCenter
]
removeObserver
:
self
];
[placeHolderLabel
release
]; placeHolderLabel =
nil
;
[placeholderColor
release
]; placeholderColor =
nil
;
[placeholder
release
]; placeholder =
nil
;
[
super
dealloc
];
}
- (
void
)awakeFromNib
{
[
super
awakeFromNib
];
[
self
setPlaceholder
:
@""
];
[
self
setPlaceholderColor
:[
UIColor
lightGrayColor
]];
[[
NSNotificationCenter
defaultCenter
]
addObserver
:
self
selector
:
@selector
(textChanged:)
name
:
UITextViewTextDidChangeNotification
object
:nil
];
}
- (
id
)initWithFrame:(CGRect)frame
{
if
( (
self
= [
super
initWithFrame
:frame]) )
{
[
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
;
}
if
([[
self
text
]
length
] ==
0
)
{
[[
self
viewWithTag
:
9
9
9
]
setAlpha
:
1
];
}
else
{
[[
self
viewWithTag
:
9
9
9
]
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
-
1
6
,
0
)];
placeHolderLabel
.lineBreakMode
=
UILineBreakModeWordWrap
;
placeHolderLabel
.numberOfLines
=
0
;
placeHolderLabel
.font
=
self
.font
;
placeHolderLabel
.backgroundColor
= [
UIColor
clearColor
];
placeHolderLabel
.textColor
=
self
.placeholderColor
;
placeHolderLabel
.alpha
=
0
;
placeHolderLabel
.tag
=
9
9
9
;
[
self
addSubview
:placeHolderLabel];
}
placeHolderLabel
.text
=
self
.placeholder
;
[placeHolderLabel
sizeToFit
];
[
self
sendSubviewToBack
:placeHolderLabel];
}
if
( [[
self
text
]
length
] ==
0
&& [[
self
placeholder
]
length
] >
0
)
{
[[
self
viewWithTag
:
9
9
9
]
setAlpha
:
1
];
}
[
super
drawRect
:rect];
}
@end