Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #2 from gurd/master

Merge placeholder, animation duration, and optimized height calculation.
  • Loading branch information...
commit d35ca39d79e6c1d47959500bba9e2cff7cd0a9aa 2 parents e642a37 + 6483dc9
@egoldfarb egoldfarb authored
View
1  README.md
@@ -10,6 +10,7 @@ Properties
* `int maxNumberOfLines;` – Stops growing at this amount of lines.
* `int minNumberOfLines;` – Starts growing at this amount of lines.
* `BOOL animateHeightChange;` – Animate the growing
+* `NSTimeInterval animationDuration;` – Adjust the duration of the growth animation.
UITextView properties
View
12 class/HPGrowingTextView.h
@@ -52,14 +52,15 @@
@interface HPGrowingTextView : UIView <UITextViewDelegate> {
HPTextViewInternal *internalTextView;
- int minHeight;
- int maxHeight;
+ CGFloat minHeight;
+ CGFloat maxHeight;
//class properties
int maxNumberOfLines;
int minNumberOfLines;
BOOL animateHeightChange;
+ NSTimeInterval animationDuration;
//uitextview properties
NSObject <HPGrowingTextViewDelegate> *__unsafe_unretained delegate;
@@ -76,11 +77,17 @@
@property int maxNumberOfLines;
@property int minNumberOfLines;
@property BOOL animateHeightChange;
+@property NSTimeInterval animationDuration;
+@property (readonly) BOOL isAnimating;
+@property (nonatomic, strong) NSString *placeholder;
+@property (nonatomic, strong) UIColor *placeholderColor;
@property (nonatomic, strong) UITextView *internalTextView;
//uitextview properties
@property(unsafe_unretained) NSObject<HPGrowingTextViewDelegate> *delegate;
+@property(nonatomic,assign) CGFloat minHeight;
+@property(nonatomic,assign) CGFloat maxHeight;
@property(nonatomic,strong) NSString *text;
@property(nonatomic,strong) UIFont *font;
@property(nonatomic,strong) UIColor *textColor;
@@ -100,5 +107,6 @@
- (BOOL)hasText;
- (void)scrollRangeToVisible:(NSRange)range;
+- (void)resetSize;
@end
View
128 class/HPGrowingTextView.m
@@ -27,11 +27,13 @@
#import "HPGrowingTextView.h"
#import "HPTextViewInternal.h"
+#import <QuartzCore/QuartzCore.h>
@interface HPGrowingTextView(private)
-(void)commonInitialiser;
--(void)resizeTextView:(NSInteger)newSizeH;
+-(void)resizeTextView:(CGFloat)newSizeH;
-(void)growDidStop;
+-(void)sizeToFitMaxHeight;
@end
@implementation HPGrowingTextView
@@ -45,7 +47,11 @@ @implementation HPGrowingTextView
@synthesize editable;
@synthesize dataDetectorTypes;
@synthesize animateHeightChange;
+@synthesize animationDuration;
@synthesize returnKeyType;
+@synthesize minHeight, maxHeight;
+@dynamic placeholder;
+@dynamic placeholderColor;
// having initwithcoder allows us to use HPGrowingTextView in a Nib. -- aob, 9/2011
- (id)initWithCoder:(NSCoder *)aDecoder
@@ -82,30 +88,31 @@ -(void)commonInitialiser
minNumberOfLines = 1;
animateHeightChange = YES;
+ animationDuration = 0.1f;
internalTextView.text = @"";
[self setMaxNumberOfLines:3];
+
+ [self setPlaceholderColor:[UIColor lightGrayColor]];
+ internalTextView.displayPlaceHolder = YES;
}
--(CGSize)sizeThatFits:(CGSize)size
+-(void)sizeToFit
{
- if (self.text.length == 0) {
- size.height = minHeight;
- }
- return size;
+ [self sizeToFitMaxHeight];
}
--(void)layoutSubviews
+-(void)setFrame:(CGRect)aframe
{
- [super layoutSubviews];
-
- CGRect r = self.bounds;
+ CGRect r = aframe;
r.origin.y = 0;
r.origin.x = contentInset.left;
r.size.width -= contentInset.left + contentInset.right;
- internalTextView.frame = r;
+ internalTextView.frame = r;
+
+ [super setFrame:aframe];
}
-(void)setContentInset:(UIEdgeInsets)inset
@@ -186,31 +193,80 @@ -(int)minNumberOfLines
return minNumberOfLines;
}
+- (NSString *)placeholder
+{
+ return internalTextView.placeholder;
+}
+- (void)setMinHeight:(CGFloat)height
+{
+ minHeight = height;
+
+ [self sizeToFit];
+}
-- (void)textViewDidChange:(UITextView *)textView
-{
+- (void)setPlaceholder:(NSString *)placeholder
+{
+ [internalTextView setPlaceholder:placeholder];
+}
+
+- (UIColor *)placeholderColor
+{
+ return internalTextView.placeholderColor;
+}
+
+- (void)setPlaceholderColor:(UIColor *)placeholderColor
+{
+ [internalTextView setPlaceholderColor:placeholderColor];
+}
+
+- (BOOL)isAnimating
+{
+ return (self.layer.animationKeys.count > 0);
+}
+
+- (void)refreshPlaceholder
+{
+ // Display (or not) the placeholder string
+
+ BOOL wasDisplayingPlaceholder = internalTextView.displayPlaceHolder;
+ internalTextView.displayPlaceHolder = self.internalTextView.text.length == 0 && !self.isAnimating;
+
+ if (wasDisplayingPlaceholder != internalTextView.displayPlaceHolder) {
+ [internalTextView setNeedsDisplay];
+ }
+}
+
+- (void)setMaxHeight:(CGFloat)height
+{
+ maxHeight = height;
+
+ [self sizeToFit];
+}
+
+- (void) sizeToFitMaxHeight
+{
//size of content, so we can set the frame of self
- NSInteger newSizeH = internalTextView.contentSize.height;
+ CGFloat newSizeH = internalTextView.contentSize.height;
if(newSizeH < minHeight || !internalTextView.hasText) newSizeH = minHeight; //not smalles than minHeight
if (internalTextView.frame.size.height > maxHeight) newSizeH = maxHeight; // not taller than maxHeight
+ // [fixed] Pasting too much text into the view failed to fire the height change,
+ // thanks to Gwynne <http://blog.darkrainfall.org/>
+
+ if (newSizeH > maxHeight && internalTextView.frame.size.height <= maxHeight)
+ {
+ newSizeH = maxHeight;
+ }
+
if (internalTextView.frame.size.height != newSizeH)
{
- // [fixed] Pasting too much text into the view failed to fire the height change,
- // thanks to Gwynne <http://blog.darkrainfall.org/>
-
- if (newSizeH > maxHeight && internalTextView.frame.size.height <= maxHeight)
- {
- newSizeH = maxHeight;
- }
-
if (newSizeH <= maxHeight)
{
if(animateHeightChange) {
if ([UIView resolveClassMethod:@selector(animateWithDuration:animations:)]) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
- [UIView animateWithDuration:0.1f
+ [UIView animateWithDuration:animationDuration
delay:0
options:(UIViewAnimationOptionAllowUserInteraction|
UIViewAnimationOptionBeginFromCurrentState)
@@ -221,11 +277,12 @@ - (void)textViewDidChange:(UITextView *)textView
if ([delegate respondsToSelector:@selector(growingTextView:didChangeHeight:)]) {
[delegate growingTextView:self didChangeHeight:newSizeH];
}
+ [self refreshPlaceholder];
}];
#endif
} else {
[UIView beginAnimations:@"" context:nil];
- [UIView setAnimationDuration:0.1f];
+ [UIView setAnimationDuration:animationDuration];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(growDidStop)];
[UIView setAnimationBeginsFromCurrentState:YES];
@@ -257,17 +314,26 @@ - (void)textViewDidChange:(UITextView *)textView
} else {
internalTextView.scrollEnabled = NO;
}
-
}
+}
+
+
+- (void)textViewDidChange:(UITextView *)textView
+{
+ [self sizeToFitMaxHeight];
+ // Display (or not) the placeholder string
+ [self refreshPlaceholder];
+
+ // Tell the delegate that the text view changed
- if ([delegate respondsToSelector:@selector(growingTextViewDidChange:)]) {
+ if ([delegate respondsToSelector:@selector(growingTextViewDidChange:)]) {
[delegate growingTextViewDidChange:self];
}
}
--(void)resizeTextView:(NSInteger)newSizeH
+-(void)resizeTextView:(CGFloat)newSizeH
{
if ([delegate respondsToSelector:@selector(growingTextView:willChangeHeight:)]) {
[delegate growingTextView:self willChangeHeight:newSizeH];
@@ -289,7 +355,8 @@ -(void)growDidStop
if ([delegate respondsToSelector:@selector(growingTextView:didChangeHeight:)]) {
[delegate growingTextView:self didChangeHeight:self.frame.size.height];
}
-
+
+ [self refreshPlaceholder];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
@@ -534,6 +601,11 @@ - (void)textViewDidChangeSelection:(UITextView *)textView {
}
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+- (void)resetSize{
+ [self performSelector:@selector(textViewDidChange:) withObject:internalTextView];
+}
+
@end
View
7 class/HPTextViewInternal.h
@@ -28,7 +28,10 @@
#import <UIKit/UIKit.h>
-@interface HPTextViewInternal : UITextView {
-}
+@interface HPTextViewInternal : UITextView
+
+@property (nonatomic, strong) NSString *placeholder;
+@property (nonatomic, strong) UIColor *placeholderColor;
+@property (nonatomic) BOOL displayPlaceHolder;
@end
View
14 class/HPTextViewInternal.m
@@ -30,6 +30,10 @@
@implementation HPTextViewInternal
+@synthesize placeholder;
+@synthesize placeholderColor;
+@synthesize displayPlaceHolder;
+
-(void)setText:(NSString *)text
{
BOOL originalValue = self.scrollEnabled;
@@ -89,7 +93,13 @@ -(void)setContentSize:(CGSize)contentSize
[super setContentSize:contentSize];
}
-
-
+- (void)drawRect:(CGRect)rect
+{
+ [super drawRect:rect];
+ if (displayPlaceHolder && placeholder && placeholderColor) {
+ [placeholderColor set];
+ [placeholder drawInRect:CGRectMake(8.0f, 8.0f, self.frame.size.width - 16.0f, self.frame.size.height - 16.0f) withFont:self.font];
+ }
+}
@end
Please sign in to comment.
Something went wrong with that request. Please try again.