Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial import from http://www.hanspinckaers.com/multi-line-uitextvie…

…w-similar-to-sms (MIT license)
  • Loading branch information...
commit 3dc2fa4cb16a6a63861ea65b180b08e7c48e08cc 0 parents
Hwee-Boon Yar authored July 20, 2011
14  .gitignore
... ...
@@ -0,0 +1,14 @@
  1
+# OS X noise
  2
+.DS_Store
  3
+
  4
+# vi swap files
  5
+*.swp
  6
+
  7
+# Xcode noise
  8
+build/
  9
+*.pbxuser
  10
+*.mode1v3
  11
+config
  12
+
  13
+# Other tools
  14
+tags
21  LICENSE.txt
... ...
@@ -0,0 +1,21 @@
  1
+MIT License
  2
+
  3
+Copyright (c) 2011 Hans Pinckaers
  4
+
  5
+Permission is hereby granted, free of charge, to any person obtaining a copy
  6
+of this software and associated documentation files (the "Software"), to deal
  7
+in the Software without restriction, including without limitation the rights
  8
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9
+copies of the Software, and to permit persons to whom the Software is
  10
+furnished to do so, subject to the following conditions:
  11
+
  12
+The above copyright notice and this permission notice shall be included in
  13
+all copies or substantial portions of the Software.
  14
+
  15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21
+THE SOFTWARE.
99  class/HPGrowingTextView.h
... ...
@@ -0,0 +1,99 @@
  1
+//
  2
+//  HPTextView.h
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//
  10
+//	Permission is hereby granted, free of charge, to any person obtaining a copy
  11
+//	of this software and associated documentation files (the "Software"), to deal
  12
+//	in the Software without restriction, including without limitation the rights
  13
+//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14
+//	copies of the Software, and to permit persons to whom the Software is
  15
+//	furnished to do so, subject to the following conditions:
  16
+//
  17
+//	The above copyright notice and this permission notice shall be included in
  18
+//	all copies or substantial portions of the Software.
  19
+//
  20
+//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21
+//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22
+//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23
+//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24
+//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25
+//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26
+//	THE SOFTWARE.
  27
+
  28
+#import <UIKit/UIKit.h>
  29
+
  30
+@class HPGrowingTextView;
  31
+@class HPTextViewInternal;
  32
+
  33
+@protocol HPGrowingTextViewDelegate
  34
+
  35
+@optional
  36
+- (BOOL)growingTextViewShouldBeginEditing:(HPGrowingTextView *)growingTextView;
  37
+- (BOOL)growingTextViewShouldEndEditing:(HPGrowingTextView *)growingTextView;
  38
+
  39
+- (void)growingTextViewDidBeginEditing:(HPGrowingTextView *)growingTextView;
  40
+- (void)growingTextViewDidEndEditing:(HPGrowingTextView *)growingTextView;
  41
+
  42
+- (BOOL)growingTextView:(HPGrowingTextView *)growingTextView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
  43
+- (void)growingTextViewDidChange:(HPGrowingTextView *)growingTextView;
  44
+
  45
+- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height;
  46
+- (void)growingTextView:(HPGrowingTextView *)growingTextView didChangeHeight:(float)height;
  47
+
  48
+- (void)growingTextViewDidChangeSelection:(HPGrowingTextView *)growingTextView;
  49
+- (BOOL)growingTextViewShouldReturn:(HPGrowingTextView *)growingTextView;
  50
+@end
  51
+
  52
+@interface HPGrowingTextView : UIView <UITextViewDelegate> {
  53
+	HPTextViewInternal *internalTextView;	
  54
+	
  55
+	int minHeight;
  56
+	int maxHeight;
  57
+	
  58
+	//class properties
  59
+	int maxNumberOfLines;
  60
+	int minNumberOfLines;
  61
+	
  62
+	BOOL animateHeightChange;
  63
+	
  64
+	//uitextview properties
  65
+	NSObject <HPGrowingTextViewDelegate> *delegate;
  66
+	NSString *text;
  67
+	UIFont *font;
  68
+	UIColor *textColor;
  69
+	UITextAlignment textAlignment; 
  70
+	NSRange selectedRange;
  71
+	BOOL editable;
  72
+	UIDataDetectorTypes dataDetectorTypes;
  73
+	UIReturnKeyType returnKeyType;
  74
+}
  75
+
  76
+//real class properties
  77
+@property int maxNumberOfLines;
  78
+@property int minNumberOfLines;
  79
+@property BOOL animateHeightChange;
  80
+@property (retain) UITextView *internalTextView;	
  81
+
  82
+
  83
+//uitextview properties
  84
+@property(assign) NSObject<HPGrowingTextViewDelegate> *delegate;
  85
+@property(nonatomic,assign) NSString *text;
  86
+@property(nonatomic,assign) UIFont *font;
  87
+@property(nonatomic,assign) UIColor *textColor;
  88
+@property(nonatomic) UITextAlignment textAlignment;    // default is UITextAlignmentLeft
  89
+@property(nonatomic) NSRange selectedRange;            // only ranges of length 0 are supported
  90
+@property(nonatomic,getter=isEditable) BOOL editable;
  91
+@property(nonatomic) UIDataDetectorTypes dataDetectorTypes __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_3_0);
  92
+@property (nonatomic) UIReturnKeyType returnKeyType;
  93
+
  94
+
  95
+//uitextview methods
  96
+- (BOOL)hasText;
  97
+- (void)scrollRangeToVisible:(NSRange)range;
  98
+
  99
+@end
419  class/HPGrowingTextView.m
... ...
@@ -0,0 +1,419 @@
  1
+//
  2
+//  HPTextView.m
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//
  10
+//	Permission is hereby granted, free of charge, to any person obtaining a copy
  11
+//	of this software and associated documentation files (the "Software"), to deal
  12
+//	in the Software without restriction, including without limitation the rights
  13
+//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14
+//	copies of the Software, and to permit persons to whom the Software is
  15
+//	furnished to do so, subject to the following conditions:
  16
+//
  17
+//	The above copyright notice and this permission notice shall be included in
  18
+//	all copies or substantial portions of the Software.
  19
+//
  20
+//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21
+//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22
+//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23
+//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24
+//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25
+//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26
+//	THE SOFTWARE.
  27
+
  28
+#import "HPGrowingTextView.h"
  29
+#import "HPTextViewInternal.h"
  30
+
  31
+
  32
+@implementation HPGrowingTextView
  33
+@synthesize internalTextView;
  34
+@synthesize maxNumberOfLines;
  35
+@synthesize minNumberOfLines;
  36
+@synthesize delegate;
  37
+
  38
+@synthesize text;
  39
+@synthesize font;
  40
+@synthesize textColor;
  41
+@synthesize textAlignment; 
  42
+@synthesize selectedRange;
  43
+@synthesize editable;
  44
+@synthesize dataDetectorTypes; 
  45
+@synthesize animateHeightChange;
  46
+@synthesize returnKeyType;
  47
+
  48
+
  49
+- (id)initWithFrame:(CGRect)frame {
  50
+    if ((self = [super initWithFrame:frame])) {
  51
+        // Initialization code
  52
+		CGRect r = frame;
  53
+		r.origin.y = 0;
  54
+		r.origin.x = 0;
  55
+		
  56
+		internalTextView = [[HPTextViewInternal alloc] initWithFrame:r];
  57
+		internalTextView.delegate = self;
  58
+		internalTextView.scrollEnabled = NO;
  59
+		internalTextView.font = [UIFont fontWithName:@"Helvetica" size:13]; 
  60
+		internalTextView.contentInset = UIEdgeInsetsZero;		
  61
+		internalTextView.showsHorizontalScrollIndicator = NO;
  62
+		internalTextView.text = @"-";
  63
+		[self addSubview:internalTextView];
  64
+		
  65
+		UIView *internal = (UIView*)[[internalTextView subviews] objectAtIndex:0];
  66
+		minHeight = internal.frame.size.height;
  67
+		minNumberOfLines = 1;
  68
+		
  69
+		animateHeightChange = YES;
  70
+		
  71
+		internalTextView.text = @"";
  72
+		
  73
+		[self setMaxNumberOfLines:3];
  74
+    }
  75
+    return self;
  76
+}
  77
+
  78
+-(void)sizeToFit
  79
+{
  80
+	CGRect r = self.frame;
  81
+	r.size.height = minHeight;
  82
+	self.frame = r;
  83
+}
  84
+
  85
+-(void)setFrame:(CGRect)aframe
  86
+{
  87
+	CGRect r = aframe;
  88
+	r.origin.y = 0;
  89
+	r.origin.x = 0;
  90
+	internalTextView.frame = r;
  91
+	
  92
+	[super setFrame:aframe];
  93
+}
  94
+
  95
+-(void)setMaxNumberOfLines:(int)n
  96
+{
  97
+	UITextView *test = [[HPTextViewInternal alloc] init];	
  98
+	test.font = internalTextView.font;
  99
+	test.hidden = YES;
  100
+	
  101
+	NSMutableString *newLines = [NSMutableString string];
  102
+	
  103
+	if(n == 1){
  104
+		[newLines appendString:@"-"];
  105
+	} else {
  106
+		for(int i = 1; i<n; i++){
  107
+			[newLines appendString:@"\n"];
  108
+		}
  109
+	}
  110
+	
  111
+	test.text = newLines;
  112
+	
  113
+	
  114
+	[self addSubview:test];
  115
+
  116
+	maxHeight = test.contentSize.height;
  117
+	maxNumberOfLines = n;
  118
+	
  119
+	[test removeFromSuperview];
  120
+	[test release];	
  121
+}
  122
+
  123
+-(void)setMinNumberOfLines:(int)m
  124
+{
  125
+	
  126
+	UITextView *test = [[HPTextViewInternal alloc] init];	
  127
+	test.font = internalTextView.font;
  128
+	test.hidden = YES;
  129
+	
  130
+	NSMutableString *newLines = [NSMutableString string];
  131
+ 
  132
+	if(m == 1){
  133
+		[newLines appendString:@"-"];
  134
+	} else {
  135
+		for(int i = 1; i<m; i++){
  136
+			[newLines appendString:@"\n"];
  137
+		}
  138
+	}
  139
+	
  140
+	test.text = newLines;
  141
+	
  142
+	
  143
+	[self addSubview:test];
  144
+	
  145
+	minHeight = test.contentSize.height;
  146
+			
  147
+	[self sizeToFit];	
  148
+	minNumberOfLines = m;
  149
+	
  150
+	[test removeFromSuperview];
  151
+	[test release];
  152
+}
  153
+
  154
+
  155
+- (void)textViewDidChange:(UITextView *)textView
  156
+{
  157
+	//size of content, so we can set the frame of self
  158
+	NSInteger newSizeH = internalTextView.contentSize.height;
  159
+	if(newSizeH < minHeight || !internalTextView.hasText) newSizeH = minHeight; //not smalles than minHeight
  160
+	 
  161
+	if (internalTextView.frame.size.height != newSizeH)
  162
+	{
  163
+		if (newSizeH <= maxHeight)
  164
+		{
  165
+			if(animateHeightChange){
  166
+				[UIView beginAnimations:@"" context:nil];
  167
+				[UIView setAnimationDelegate:self];
  168
+				[UIView setAnimationDidStopSelector:@selector(growDidStop)];
  169
+				[UIView setAnimationBeginsFromCurrentState:YES];
  170
+			}
  171
+			
  172
+			if ([delegate respondsToSelector:@selector(growingTextView:willChangeHeight:)]) {
  173
+				[delegate growingTextView:self willChangeHeight:newSizeH];
  174
+			}
  175
+			
  176
+			// internalTextView
  177
+			CGRect internalTextViewFrame = self.frame;
  178
+			internalTextViewFrame.size.height = newSizeH; // + padding
  179
+			self.frame = internalTextViewFrame;
  180
+			
  181
+			internalTextViewFrame.origin.y = 0;
  182
+			internalTextViewFrame.origin.x = 0;
  183
+			internalTextView.frame = internalTextViewFrame;
  184
+			
  185
+			if(animateHeightChange){
  186
+				[UIView commitAnimations];
  187
+			}			
  188
+		}
  189
+		
  190
+				
  191
+        // if our new height is greater than the maxHeight
  192
+        // sets not set the height or move things
  193
+        // around and enable scrolling
  194
+		if (newSizeH >= maxHeight)
  195
+		{
  196
+			if(!internalTextView.scrollEnabled){
  197
+				internalTextView.scrollEnabled = YES;
  198
+				[internalTextView flashScrollIndicators];
  199
+			}
  200
+			
  201
+		} else {
  202
+			internalTextView.scrollEnabled = NO;
  203
+		}
  204
+		
  205
+	}
  206
+	
  207
+	
  208
+	if ([delegate respondsToSelector:@selector(growingTextViewDidChange:)]) {
  209
+		[delegate growingTextViewDidChange:self];
  210
+	}
  211
+	
  212
+}
  213
+
  214
+-(void)growDidStop
  215
+{
  216
+	if ([delegate respondsToSelector:@selector(growingTextView:didChangeHeight:)]) {
  217
+		[delegate growingTextView:self didChangeHeight:self.frame.size.height];
  218
+	}
  219
+	
  220
+}
  221
+
  222
+-(BOOL)resignFirstResponder
  223
+{
  224
+	[super resignFirstResponder];
  225
+	return [internalTextView resignFirstResponder];
  226
+}
  227
+
  228
+- (void)dealloc {
  229
+	[internalTextView release];
  230
+    [super dealloc];
  231
+}
  232
+
  233
+
  234
+///////////////////////////////////////////////////////////////////////////////////////////////////
  235
+#pragma mark UITextView properties
  236
+///////////////////////////////////////////////////////////////////////////////////////////////////
  237
+
  238
+-(void)setText:(NSString *)atext
  239
+{
  240
+	internalTextView.text= atext;
  241
+}
  242
+//
  243
+-(NSString*)text
  244
+{
  245
+	return internalTextView.text;
  246
+}
  247
+
  248
+///////////////////////////////////////////////////////////////////////////////////////////////////
  249
+
  250
+-(void)setFont:(UIFont *)afont
  251
+{
  252
+	internalTextView.font= afont;
  253
+	
  254
+	[self setMaxNumberOfLines:maxNumberOfLines];
  255
+	[self setMinNumberOfLines:minNumberOfLines];
  256
+}
  257
+
  258
+-(UIFont *)font
  259
+{
  260
+	return internalTextView.font;
  261
+}	
  262
+
  263
+///////////////////////////////////////////////////////////////////////////////////////////////////
  264
+
  265
+-(void)setTextColor:(UIColor *)color
  266
+{
  267
+	internalTextView.textColor = color;
  268
+}
  269
+
  270
+-(UIColor*)textColor{
  271
+	return internalTextView.textColor;
  272
+}
  273
+
  274
+///////////////////////////////////////////////////////////////////////////////////////////////////
  275
+
  276
+-(void)setTextAlignment:(UITextAlignment)aligment
  277
+{
  278
+	internalTextView.textAlignment = aligment;
  279
+}
  280
+
  281
+-(UITextAlignment)textAlignment
  282
+{
  283
+	return internalTextView.textAlignment;
  284
+}
  285
+
  286
+///////////////////////////////////////////////////////////////////////////////////////////////////
  287
+
  288
+-(void)setSelectedRange:(NSRange)range
  289
+{
  290
+	internalTextView.selectedRange = range;
  291
+}
  292
+
  293
+-(NSRange)selectedRange
  294
+{
  295
+	return internalTextView.selectedRange;
  296
+}
  297
+
  298
+///////////////////////////////////////////////////////////////////////////////////////////////////
  299
+
  300
+-(void)setEditable:(BOOL)beditable
  301
+{
  302
+	internalTextView.editable = beditable;
  303
+}
  304
+
  305
+-(BOOL)isEditable
  306
+{
  307
+	return internalTextView.editable;
  308
+}
  309
+
  310
+///////////////////////////////////////////////////////////////////////////////////////////////////
  311
+
  312
+-(void)setReturnKeyType:(UIReturnKeyType)keyType
  313
+{
  314
+	internalTextView.returnKeyType = keyType;
  315
+}
  316
+
  317
+-(UIReturnKeyType)returnKeyType
  318
+{
  319
+	return internalTextView.returnKeyType;
  320
+}
  321
+
  322
+///////////////////////////////////////////////////////////////////////////////////////////////////
  323
+
  324
+-(void)setDataDetectorTypes:(UIDataDetectorTypes)datadetector
  325
+{
  326
+	internalTextView.dataDetectorTypes = datadetector;
  327
+}
  328
+
  329
+-(UIDataDetectorTypes)dataDetectorTypes
  330
+{
  331
+	return internalTextView.dataDetectorTypes;
  332
+}
  333
+
  334
+///////////////////////////////////////////////////////////////////////////////////////////////////
  335
+
  336
+- (BOOL)hasText{
  337
+	return [internalTextView hasText];
  338
+}
  339
+
  340
+- (void)scrollRangeToVisible:(NSRange)range
  341
+{
  342
+	[internalTextView scrollRangeToVisible:range];
  343
+}
  344
+
  345
+/////////////////////////////////////////////////////////////////////////////////////////////////////
  346
+/////////////////////////////////////////////////////////////////////////////////////////////////////
  347
+#pragma mark -
  348
+#pragma mark UITextViewDelegate
  349
+
  350
+
  351
+///////////////////////////////////////////////////////////////////////////////////////////////////
  352
+- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
  353
+	if ([delegate respondsToSelector:@selector(growingTextViewShouldBeginEditing:)]) {
  354
+		return [delegate growingTextViewShouldBeginEditing:self];
  355
+		
  356
+	} else {
  357
+		return YES;
  358
+	}
  359
+}
  360
+
  361
+
  362
+///////////////////////////////////////////////////////////////////////////////////////////////////
  363
+- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
  364
+	if ([delegate respondsToSelector:@selector(growingTextViewShouldEndEditing:)]) {
  365
+		return [delegate growingTextViewShouldEndEditing:self];
  366
+		
  367
+	} else {
  368
+		return YES;
  369
+	}
  370
+}
  371
+
  372
+
  373
+///////////////////////////////////////////////////////////////////////////////////////////////////
  374
+- (void)textViewDidBeginEditing:(UITextView *)textView {
  375
+	if ([delegate respondsToSelector:@selector(growingTextViewDidBeginEditing:)]) {
  376
+		[delegate growingTextViewDidBeginEditing:self];
  377
+	}
  378
+}
  379
+
  380
+
  381
+///////////////////////////////////////////////////////////////////////////////////////////////////
  382
+- (void)textViewDidEndEditing:(UITextView *)textView {		
  383
+	if ([delegate respondsToSelector:@selector(growingTextViewDidEndEditing:)]) {
  384
+		[delegate growingTextViewDidEndEditing:self];
  385
+	}
  386
+}
  387
+
  388
+
  389
+///////////////////////////////////////////////////////////////////////////////////////////////////
  390
+- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
  391
+	replacementText:(NSString *)atext {
  392
+	
  393
+	//weird 1 pixel bug when clicking backspace when textView is empty
  394
+	if(![textView hasText] && [atext isEqualToString:@""]) return NO;
  395
+	
  396
+	if ([atext isEqualToString:@"\n"]) {
  397
+		if ([delegate respondsToSelector:@selector(growingTextViewShouldReturn:)]) {
  398
+			if (![delegate performSelector:@selector(growingTextViewShouldReturn:) withObject:self]) {
  399
+				return YES;
  400
+			} else {
  401
+				[textView resignFirstResponder];
  402
+				return NO;
  403
+			}
  404
+		}
  405
+	}
  406
+	
  407
+	return YES;
  408
+	
  409
+
  410
+}
  411
+
  412
+///////////////////////////////////////////////////////////////////////////////////////////////////
  413
+- (void)textViewDidChangeSelection:(UITextView *)textView {
  414
+	if ([delegate respondsToSelector:@selector(growingTextViewDidChangeSelection:)]) {
  415
+		[delegate growingTextViewDidChangeSelection:self];
  416
+	}
  417
+}
  418
+
  419
+@end
34  class/HPTextViewInternal.h
... ...
@@ -0,0 +1,34 @@
  1
+//
  2
+//  HPTextViewInternal.h
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//
  10
+//	Permission is hereby granted, free of charge, to any person obtaining a copy
  11
+//	of this software and associated documentation files (the "Software"), to deal
  12
+//	in the Software without restriction, including without limitation the rights
  13
+//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14
+//	copies of the Software, and to permit persons to whom the Software is
  15
+//	furnished to do so, subject to the following conditions:
  16
+//
  17
+//	The above copyright notice and this permission notice shall be included in
  18
+//	all copies or substantial portions of the Software.
  19
+//
  20
+//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21
+//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22
+//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23
+//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24
+//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25
+//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26
+//	THE SOFTWARE.
  27
+
  28
+#import <UIKit/UIKit.h>
  29
+
  30
+
  31
+@interface HPTextViewInternal : UITextView {
  32
+}
  33
+
  34
+@end
66  class/HPTextViewInternal.m
... ...
@@ -0,0 +1,66 @@
  1
+//
  2
+//  HPTextViewInternal.m
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//
  10
+//	Permission is hereby granted, free of charge, to any person obtaining a copy
  11
+//	of this software and associated documentation files (the "Software"), to deal
  12
+//	in the Software without restriction, including without limitation the rights
  13
+//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14
+//	copies of the Software, and to permit persons to whom the Software is
  15
+//	furnished to do so, subject to the following conditions:
  16
+//
  17
+//	The above copyright notice and this permission notice shall be included in
  18
+//	all copies or substantial portions of the Software.
  19
+//
  20
+//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21
+//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22
+//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23
+//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24
+//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25
+//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26
+//	THE SOFTWARE.
  27
+
  28
+#import "HPTextViewInternal.h"
  29
+
  30
+
  31
+@implementation HPTextViewInternal
  32
+
  33
+-(void)setContentOffset:(CGPoint)s
  34
+{
  35
+	if(self.tracking || self.decelerating){
  36
+		//initiated by user...
  37
+		self.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
  38
+	} else {
  39
+
  40
+		float bottomOffset = (self.contentSize.height - self.frame.size.height + self.contentInset.bottom);
  41
+		if(s.y < bottomOffset && self.scrollEnabled){
  42
+			self.contentInset = UIEdgeInsetsMake(0, 0, 8, 0); //maybe use scrollRangeToVisible?
  43
+		}
  44
+		
  45
+	}
  46
+	
  47
+	[super setContentOffset:s];
  48
+}
  49
+
  50
+-(void)setContentInset:(UIEdgeInsets)s
  51
+{
  52
+	UIEdgeInsets insets = s;
  53
+	
  54
+	if(s.bottom>8) insets.bottom = 0;
  55
+	insets.top = 0;
  56
+
  57
+	[super setContentInset:insets];
  58
+}
  59
+
  60
+
  61
+- (void)dealloc {
  62
+    [super dealloc];
  63
+}
  64
+
  65
+
  66
+@end
41  example/Classes/GrowingTextViewExampleAppDelegate.h
... ...
@@ -0,0 +1,41 @@
  1
+//
  2
+//  GrowingTextViewExampleAppDelegate.h
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//
  10
+//	Permission is hereby granted, free of charge, to any person obtaining a copy
  11
+//	of this software and associated documentation files (the "Software"), to deal
  12
+//	in the Software without restriction, including without limitation the rights
  13
+//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14
+//	copies of the Software, and to permit persons to whom the Software is
  15
+//	furnished to do so, subject to the following conditions:
  16
+//
  17
+//	The above copyright notice and this permission notice shall be included in
  18
+//	all copies or substantial portions of the Software.
  19
+//
  20
+//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21
+//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22
+//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23
+//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24
+//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25
+//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26
+//	THE SOFTWARE.
  27
+
  28
+#import <UIKit/UIKit.h>
  29
+
  30
+@class GrowingTextViewExampleViewController;
  31
+
  32
+@interface GrowingTextViewExampleAppDelegate : NSObject <UIApplicationDelegate> {
  33
+    UIWindow *window;
  34
+    GrowingTextViewExampleViewController *viewController;
  35
+}
  36
+
  37
+@property (nonatomic, retain) IBOutlet UIWindow *window;
  38
+@property (nonatomic, retain) GrowingTextViewExampleViewController *viewController;
  39
+
  40
+@end
  41
+
109  example/Classes/GrowingTextViewExampleAppDelegate.m
... ...
@@ -0,0 +1,109 @@
  1
+//
  2
+//  GrowingTextViewExampleAppDelegate.m
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//
  10
+//	Permission is hereby granted, free of charge, to any person obtaining a copy
  11
+//	of this software and associated documentation files (the "Software"), to deal
  12
+//	in the Software without restriction, including without limitation the rights
  13
+//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14
+//	copies of the Software, and to permit persons to whom the Software is
  15
+//	furnished to do so, subject to the following conditions:
  16
+//
  17
+//	The above copyright notice and this permission notice shall be included in
  18
+//	all copies or substantial portions of the Software.
  19
+//
  20
+//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21
+//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22
+//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23
+//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24
+//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25
+//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26
+//	THE SOFTWARE.
  27
+
  28
+#import "GrowingTextViewExampleAppDelegate.h"
  29
+#import "GrowingTextViewExampleViewController.h"
  30
+
  31
+@implementation GrowingTextViewExampleAppDelegate
  32
+
  33
+@synthesize window;
  34
+@synthesize viewController;
  35
+
  36
+
  37
+#pragma mark -
  38
+#pragma mark Application lifecycle
  39
+
  40
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
  41
+    
  42
+    // Override point for customization after application launch.
  43
+
  44
+	viewController = [[GrowingTextViewExampleViewController alloc] init];
  45
+	
  46
+    // Add the view controller's view to the window and display.
  47
+    [window addSubview:viewController.view];
  48
+    [window makeKeyAndVisible];
  49
+
  50
+    return YES;
  51
+}
  52
+
  53
+
  54
+- (void)applicationWillResignActive:(UIApplication *)application {
  55
+    /*
  56
+     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
  57
+     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
  58
+     */
  59
+}
  60
+
  61
+
  62
+- (void)applicationDidEnterBackground:(UIApplication *)application {
  63
+    /*
  64
+     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
  65
+     If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
  66
+     */
  67
+}
  68
+
  69
+
  70
+- (void)applicationWillEnterForeground:(UIApplication *)application {
  71
+    /*
  72
+     Called as part of  transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
  73
+     */
  74
+}
  75
+
  76
+
  77
+- (void)applicationDidBecomeActive:(UIApplication *)application {
  78
+    /*
  79
+     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
  80
+     */
  81
+}
  82
+
  83
+
  84
+- (void)applicationWillTerminate:(UIApplication *)application {
  85
+    /*
  86
+     Called when the application is about to terminate.
  87
+     See also applicationDidEnterBackground:.
  88
+     */
  89
+}
  90
+
  91
+
  92
+#pragma mark -
  93
+#pragma mark Memory management
  94
+
  95
+- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
  96
+    /*
  97
+     Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
  98
+     */
  99
+}
  100
+
  101
+
  102
+- (void)dealloc {
  103
+    [viewController release];
  104
+    [window release];
  105
+    [super dealloc];
  106
+}
  107
+
  108
+
  109
+@end
38  example/Classes/GrowingTextViewExampleViewController.h
... ...
@@ -0,0 +1,38 @@
  1
+//
  2
+//  GrowingTextViewExampleViewController.h
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//
  10
+//	Permission is hereby granted, free of charge, to any person obtaining a copy
  11
+//	of this software and associated documentation files (the "Software"), to deal
  12
+//	in the Software without restriction, including without limitation the rights
  13
+//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14
+//	copies of the Software, and to permit persons to whom the Software is
  15
+//	furnished to do so, subject to the following conditions:
  16
+//
  17
+//	The above copyright notice and this permission notice shall be included in
  18
+//	all copies or substantial portions of the Software.
  19
+//
  20
+//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21
+//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22
+//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23
+//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24
+//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25
+//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26
+//	THE SOFTWARE.
  27
+
  28
+#import <UIKit/UIKit.h>
  29
+#import "HPGrowingTextView.h"
  30
+
  31
+@interface GrowingTextViewExampleViewController : UIViewController <HPGrowingTextViewDelegate>{
  32
+	HPGrowingTextView *textView;
  33
+}
  34
+
  35
+-(void)resignTextView;
  36
+
  37
+@end
  38
+
162  example/Classes/GrowingTextViewExampleViewController.m
... ...
@@ -0,0 +1,162 @@
  1
+//
  2
+//  GrowingTextViewExampleViewController.m
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//
  10
+//	Permission is hereby granted, free of charge, to any person obtaining a copy
  11
+//	of this software and associated documentation files (the "Software"), to deal
  12
+//	in the Software without restriction, including without limitation the rights
  13
+//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14
+//	copies of the Software, and to permit persons to whom the Software is
  15
+//	furnished to do so, subject to the following conditions:
  16
+//
  17
+//	The above copyright notice and this permission notice shall be included in
  18
+//	all copies or substantial portions of the Software.
  19
+//
  20
+//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21
+//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22
+//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23
+//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24
+//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25
+//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26
+//	THE SOFTWARE.
  27
+
  28
+#import "GrowingTextViewExampleViewController.h"
  29
+
  30
+@implementation GrowingTextViewExampleViewController
  31
+
  32
+
  33
+-(id)init
  34
+{
  35
+	self = [super init];
  36
+	if(self){
  37
+		[[NSNotificationCenter defaultCenter] addObserver:self 
  38
+												 selector:@selector(keyboardWillShow:) 
  39
+													 name:UIKeyboardWillShowNotification 
  40
+												   object:nil];
  41
+		
  42
+		[[NSNotificationCenter defaultCenter] addObserver:self 
  43
+												 selector:@selector(keyboardWillHide:) 
  44
+													 name:UIKeyboardWillHideNotification 
  45
+												   object:nil];		
  46
+	}
  47
+	
  48
+	return self;
  49
+}
  50
+
  51
+
  52
+
  53
+// Implement loadView to create a view hierarchy programmatically, without using a nib.
  54
+- (void)loadView {
  55
+	self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
  56
+	self.view.backgroundColor = [UIColor grayColor];
  57
+	
  58
+	textView = [[HPGrowingTextView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
  59
+	textView.minNumberOfLines = 1;
  60
+	textView.maxNumberOfLines = 4;
  61
+	textView.returnKeyType = UIReturnKeyGo; //just as an example
  62
+	textView.font = [UIFont boldSystemFontOfSize:15.0f];
  63
+	textView.delegate = self;
  64
+	//textView.animateHeightChange = NO; //turns off animation
  65
+		
  66
+	[self.view addSubview:textView];
  67
+	[textView sizeToFit];
  68
+	
  69
+	UIButton *doneBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  70
+	doneBtn.frame = CGRectMake(30, 30, 260, 80);
  71
+	[doneBtn setTitle:@"Done" forState:UIControlStateNormal];
  72
+	[doneBtn addTarget:self action:@selector(resignTextView) forControlEvents:UIControlEventTouchUpInside];
  73
+	[self.view addSubview:doneBtn];
  74
+		
  75
+	CGRect r = textView.frame;
  76
+	r.origin.y = self.view.frame.size.height - r.size.height;
  77
+	textView.frame = r;		
  78
+}
  79
+
  80
+-(void)resignTextView
  81
+{
  82
+	NSLog(@"???");
  83
+	[textView resignFirstResponder];
  84
+}
  85
+
  86
+//Code from Brett Schumann
  87
+-(void) keyboardWillShow:(NSNotification *)note{
  88
+    // get keyboard size and loctaion
  89
+	CGRect keyboardBounds;
  90
+    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
  91
+	
  92
+	// get the height since this is the main value that we need.
  93
+	NSInteger kbSizeH = keyboardBounds.size.height;
  94
+		
  95
+	// get a rect for the textView frame
  96
+	CGRect textViewFrame = textView.frame;
  97
+	textViewFrame.origin.y -= kbSizeH;
  98
+	
  99
+	// animations settings
  100
+	[UIView beginAnimations:nil context:NULL];
  101
+	[UIView setAnimationBeginsFromCurrentState:YES];
  102
+    [UIView setAnimationDuration:0.3f];
  103
+	
  104
+	// set views with new info
  105
+	textView.frame = textViewFrame;
  106
+	
  107
+	// commit animations
  108
+	[UIView commitAnimations];
  109
+}
  110
+
  111
+-(void) keyboardWillHide:(NSNotification *)note{
  112
+    // get keyboard size and location
  113
+	CGRect keyboardBounds;
  114
+    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
  115
+	
  116
+	// get the height since this is the main value that we need.
  117
+	NSInteger kbSizeH = keyboardBounds.size.height;
  118
+	
  119
+	// get a rect for the textView frame
  120
+	CGRect textViewFrame = textView.frame;
  121
+	textViewFrame.origin.y += kbSizeH;
  122
+	
  123
+	// animations settings
  124
+	[UIView beginAnimations:nil context:NULL];
  125
+	[UIView setAnimationBeginsFromCurrentState:YES];
  126
+    [UIView setAnimationDuration:0.3f];
  127
+	
  128
+	// set views with new info
  129
+	textView.frame = textViewFrame;
  130
+	
  131
+	// commit animations
  132
+	[UIView commitAnimations];
  133
+}
  134
+
  135
+- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height
  136
+{
  137
+	float diff = (textView.frame.size.height - height);
  138
+		
  139
+	CGRect r = textView.frame;
  140
+	r.origin.y += diff;
  141
+	textView.frame = r;
  142
+}
  143
+
  144
+- (void)didReceiveMemoryWarning {
  145
+	// Releases the view if it doesn't have a superview.
  146
+    [super didReceiveMemoryWarning];
  147
+	
  148
+	// Release any cached data, images, etc that aren't in use.
  149
+}
  150
+
  151
+- (void)viewDidUnload {
  152
+	// Release any retained subviews of the main view.
  153
+	// e.g. self.myOutlet = nil;
  154
+}
  155
+
  156
+
  157
+- (void)dealloc {
  158
+	[textView release];
  159
+    [super dealloc];
  160
+}
  161
+
  162
+@end
99  example/Classes/HPGrowingTextView.h
... ...
@@ -0,0 +1,99 @@
  1
+//
  2
+//  HPTextView.h
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//
  10
+//	Permission is hereby granted, free of charge, to any person obtaining a copy
  11
+//	of this software and associated documentation files (the "Software"), to deal
  12
+//	in the Software without restriction, including without limitation the rights
  13
+//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14
+//	copies of the Software, and to permit persons to whom the Software is
  15
+//	furnished to do so, subject to the following conditions:
  16
+//
  17
+//	The above copyright notice and this permission notice shall be included in
  18
+//	all copies or substantial portions of the Software.
  19
+//
  20
+//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21
+//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22
+//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23
+//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24
+//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25
+//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26
+//	THE SOFTWARE.
  27
+
  28
+#import <UIKit/UIKit.h>
  29
+
  30
+@class HPGrowingTextView;
  31
+@class HPTextViewInternal;
  32
+
  33
+@protocol HPGrowingTextViewDelegate
  34
+
  35
+@optional
  36
+- (BOOL)growingTextViewShouldBeginEditing:(HPGrowingTextView *)growingTextView;
  37
+- (BOOL)growingTextViewShouldEndEditing:(HPGrowingTextView *)growingTextView;
  38
+
  39
+- (void)growingTextViewDidBeginEditing:(HPGrowingTextView *)growingTextView;
  40
+- (void)growingTextViewDidEndEditing:(HPGrowingTextView *)growingTextView;
  41
+
  42
+- (BOOL)growingTextView:(HPGrowingTextView *)growingTextView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
  43
+- (void)growingTextViewDidChange:(HPGrowingTextView *)growingTextView;
  44
+
  45
+- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height;
  46
+- (void)growingTextView:(HPGrowingTextView *)growingTextView didChangeHeight:(float)height;
  47
+
  48
+- (void)growingTextViewDidChangeSelection:(HPGrowingTextView *)growingTextView;
  49
+- (BOOL)growingTextViewShouldReturn:(HPGrowingTextView *)growingTextView;
  50
+@end
  51
+
  52
+@interface HPGrowingTextView : UIView <UITextViewDelegate> {
  53
+	HPTextViewInternal *internalTextView;	
  54
+	
  55
+	int minHeight;
  56
+	int maxHeight;
  57
+	
  58
+	//class properties
  59
+	int maxNumberOfLines;
  60
+	int minNumberOfLines;
  61
+	
  62
+	BOOL animateHeightChange;
  63
+	
  64
+	//uitextview properties
  65
+	NSObject <HPGrowingTextViewDelegate> *delegate;
  66
+	NSString *text;
  67
+	UIFont *font;
  68
+	UIColor *textColor;
  69
+	UITextAlignment textAlignment; 
  70
+	NSRange selectedRange;
  71
+	BOOL editable;
  72
+	UIDataDetectorTypes dataDetectorTypes;
  73
+	UIReturnKeyType returnKeyType;
  74
+}
  75
+
  76
+//real class properties
  77
+@property int maxNumberOfLines;
  78
+@property int minNumberOfLines;
  79
+@property BOOL animateHeightChange;
  80
+@property (retain) UITextView *internalTextView;	
  81
+
  82
+
  83
+//uitextview properties
  84
+@property(assign) NSObject<HPGrowingTextViewDelegate> *delegate;
  85
+@property(nonatomic,assign) NSString *text;
  86
+@property(nonatomic,assign) UIFont *font;
  87
+@property(nonatomic,assign) UIColor *textColor;
  88
+@property(nonatomic) UITextAlignment textAlignment;    // default is UITextAlignmentLeft
  89
+@property(nonatomic) NSRange selectedRange;            // only ranges of length 0 are supported
  90
+@property(nonatomic,getter=isEditable) BOOL editable;
  91
+@property(nonatomic) UIDataDetectorTypes dataDetectorTypes __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_3_0);
  92
+@property (nonatomic) UIReturnKeyType returnKeyType;
  93
+
  94
+
  95
+//uitextview methods
  96
+- (BOOL)hasText;
  97
+- (void)scrollRangeToVisible:(NSRange)range;
  98
+
  99
+@end
419  example/Classes/HPGrowingTextView.m
... ...
@@ -0,0 +1,419 @@
  1
+//
  2
+//  HPTextView.m
  3
+//
  4
+//  Created by Hans Pinckaers on 29-06-10.
  5
+//
  6
+//	MIT License
  7
+//
  8
+//	Copyright (c) 2011 Hans Pinckaers
  9
+//