make a textView scale horizontally as text accumulates - iphone

I am trying to make a textView frame scale horizontally as text accumulates. I am using the code blow to try to make this happen. The frame scales vertically as expected, but the size seems to be locked horizontally.
[myTextView setFrame:CGRectMake(myTextView.frame.origin.x, myTextView.frame.origin.y, myTextView.contentSize.width, myTextView.contentSize.height)];
Here is the project (27K) if anyone wants to take a look.
Thanks for reading.

Implement UITextView delegate in .h file this:
#interface ViewController : UIViewController<UITextViewDelegate>
If yourTextView added from xib then bind delegate with fileowner otherwise in ViewDidLoad add this line:
yourTextView.delegate = self;
Use textView's delegate for your requirement:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
CGSize maximumSize = CGSizeMake(2000,40); //specify height of textView and maximum width for text to fit in height of textView as u want text horizontally
CGSize *txtSize = [textView.text sizeWithFont:[UIFont fontWithName:#"Arial" size:16] constrainedToSize:maximumSize lineBreakMode:UILineBreakModeCharacterWrap]; //calulate size of text by specifying font here
//Add UIViewAnimation here if needed
[textView setFrame:CGRectMake(textView.frame.origin.x,textView.frame.origin.y,txtSize.width+10,txtSize.height+10)]; // change accordingly
return YES;
}

Your answer is here at notes-app.

Related

Text view scrolling with in a limited frame in iphone?

I had a text view above the keyboard like hangout application in iphone. i need to type the character in that as go on it will increses the content scroll with in that frame only.and also the texts needs to be in the correct allignment,I did that in this manner `
-(void)textViewDidChange:(UITextView *)textView
{
NSString *text1 = [textView text];
CGFloat width = [textView frame].size.width;
CGSize size = [text1 sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(width, 9999) lineBreakMode:UILineBreakModeWordWrap];
textView.contentSize=CGSizeMake([textView frame].size.width, size.height) ;
}
- (BOOL)textViewShouldReturn:(UITextView *)textview
{
[textView1 resignFirstResponder];
return YES;
}
- (BOOL)textViewShouldBeginEditing:(UITextView *)textField
{
//delegate=self;
return YES;
}
`But here the problem is it is dancing .not sticking.when ever i am typing the whole area is moving up and down,i need it to be fixed.and when ever i typed and reached the end point it needs to scroll up.Can any body help me in where i am going wrong?
For set contentSize of UITextView no need any code , by default it provides this so remove your whole code from textViewDidChange: method.
txtView.contentSize = CGSizeMake(320, 800);
Try this and put dis textview on scrollview.

changing the frame of UITextView as I am typing

I can use the code below to set the size of the textView frame, to approximately match the textView's content (the typed text) when I press a button or whatnot. How would I call this whenever a new character is typed, so that the frame would grow or shrink interactively?
- (IBAction)doneEditingText:(id)sender {
[myTextView resignFirstResponder];
[myTextView setFrame:CGRectMake(myTextView.frame.origin.x, myTextView.frame.origin.y, myTextView.contentSize.width, myTextView.contentSize.height)];
}
Thanks for reading
EDIT :
Implement UITextView delegate in .h file this:
#interface ViewController : UIViewController<UITextViewDelegate>
If yourTextView added from xib then bind delegate with fileowner otherwise in ViewDidLoad add this line:
yourTextView.delegate = self;
Use textView's delegate for your requirement:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
CGSize maximumSize = CGSizeMake(280,999); //specify width of textView and maximum height for text to fit in width of textView
CGSize txtSize = [textView.text sizeWithFont:[UIFont fontWithName:#"Arial" size:16] constrainedToSize:maximumSize lineBreakMode:UILineBreakModeCharacterWrap]; //calulate size of text by specifying font here
//Add UIViewAnimation here if needed
[textView setFrame:CGRectMake(textView.frame.origin.x,textView.frame.origin.y,txtSize.width+10,txtSize.height+10)]; // change accordingly
return YES;
}
You can use something like this repo on GIT which has the almost same functionality that you want-
https://github.com/HansPinckaers/GrowingTextView
it's similar like message app in iPhone.
I just got done implementing this. The problem with the current (as of posting this answer) accepted answer is that the delegate method:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
exposes the textView before the change the user has typed/inserted/deleted is commited. therefore, the resizing you would be achieving would be one character late. UITextView does inherit from a UIScrollView so the text wouldn't clip off of screen but it could lead to some awkward behavior.
My Solution is to use two delegate methods to achieve the resizing effect correctly.
Expanding the UITextView before the character the user typed hits the screen:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSMutableString *tempString = [NSMutableString stringWithString:textView.text];
[tempString replaceCharactersInRange:range withString:text];
//If we are adding to the length of the string (We might need to expand)
if([tempString length]>textView.text.length)
{
//Create a temporaryTextView which has all of the characteristics of your original textView
UITextView *tempTextView = [[UITextView alloc] initWithFrame:CGRectZero];
tempTextView.font = _inputFont;
tempTextView.contentInset = textView.contentInset;
[tempTextView setText:tempString];
//Change this to respect whatever width constraint you are trying to achieve.
CGSize theSize = [tempTextView sizeThatFits:CGSizeMake(192, CGFLOAT_MAX)];
if(theSize.height!=textView.frame.size.height)
{
textView.frame = CGRectMake(115, 310, 192,theSize.height);
return YES;
}
else
{
return YES;
}
}
else
{
return YES;
}
}
And Shrinking after the user has deleted/shrunk the amount of text in the UITextView the character
-(void)textViewDidChange:(UITextView *)textView
{
//We enter this method AFTER the edit has been drawn to the screen, therefore check to see if we should shrink.
if([textView sizeThatFits:CGSizeMake(192, CGFLOAT_MAX)].height!=textView.frame.size.height)
{
//change this to reflect the constraints of your UITextView
textView.frame = CGRectMake(115, 310, 192,[textView sizeThatFits:CGSizeMake(192, CGFLOAT_MAX)].height);
}
}

How can I get the UITextView to scroll only when it's full of text

I have this UITextView that works great except, I can't get the text inside the UITextView to start scrolling only after the UITextView's size in nearly full, the UITextView is 4 lines tall, but as soon as I reach the 2nd line the 1st line is pushed up, I don't want the view to begin scrolling until I've reached the 5 line. scrollingEnabled = NO keeps it from scrolling at all, so that didn't work.
UITextView *barf_ = [[UITextView alloc] initWithFrame:CGRectMake(20.0, 310.0, 155, 50)];
barf_.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
//[barf_ scrollRangeToVisible:NSMakeRange([barf_.text length], 0)];
barf_.layer.cornerRadius = 3.0f;
barf_.layer.borderWidth = 0.5f;
barf_.font = [UIFont fontWithName:#"Helvetica" size:13];
I found the answer, as others with similar problems have mention, with a small textView, it automatically adds 32 padding to the bottom.
A simple fix is to add YourTextView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); inside shouldChangeTextInRange method, that fixed my problem!
Setting the contentInset may help the text to appear more correctly within the UITextView. However, it won't help solve the issue whereby the UITextView has scrolling enabled despite not having more text to view.
Similarly, methods such as sizeWithFont have limitations. As explained in Mike Weller's excellent blog series iOS Development: You're Doing It Wrong, NSString isn't a good object to ask regarding how large a UIView should be. Many UIView subclasses such as UILabel, UIButton, etc. have insets and other considerations that must be accounted for during sizing. UITextLabel is no exception.
Mike Weller's particular entry on this subject is:
You're Doing It Wrong #2: Sizing labels with -[NSString sizeWithFont:...]
iOS 7 promises us more sophisticated text handling in UITextView, with properties such as textContainerInset. But what to do in the meantime?
Well, first we know that UITextView is a subclass of UIScrollView. Therefore, the golden rule that if the contentSize is larger than the view's bounds property, the scroll view will scroll so we can see more content.
Checking out contentSize agains the bounds won't work either because we know that UIScrollView is already calculating whether it should scroll or not based on the text, and it's giving us the wrong answer.
This is where arbitrary adjustment values come to the rescue! For me this value was 17.f. For you - depending on your fonts - it maybe different. We then take control and decide whether we should allow the scroll view to scroll:
static const CGFloat kArbritaryHeight = 17.f;
CGFloat adjustedContentHeight = myTextView.contentSize.height - kArbritaryHeight;
CGFloat boundsHeight = CGRectGetHeight(myTextView.bounds);
BOOL tooMuchContent = adjustedContentHeight > boundsHeight;
if (tooMuchContent)
{
myTextView.scrollEnabled = YES;
}
else
{
myTextView.scrollEnabled = NO;
}
When your UITextView is loaded set scrollEnabled to NO. Then set the text view's delegate to self or some other object and implement the UITextViewDelegate method
- (void)textViewDidChange:(UITextView *)textView
This method will get called anytime the user makes a change to the text inside the view. Inside this method you need to figure out how big your text is and if it goes beyond the bounds of the text view. If so you enable scrolling. Use this method:
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
This is a UIKit category method on NSString. It returns a CGSize that will tell you the height of whatever text string you call it on. In your case it would be something like
CGSize textSize = [textView.text sizeWithFont:textView.font
constrainedToSize:CGSizeMake(textView.frame.size.width, MAXFLOAT)
lineBreakMode:UILineBreakModeWordWrap];
if (textSize.height > textView.frame.size.height) {
textView.scrollEnabled = YES;
} else {
textView.scrollEnabled = NO;
}
You might use the sizeWithFont:constrainedToSize:lineBreakMode: method to check whether your string will actually render larger than your text view and see if you need to enable scrolling. You will have to call it any time the text in your scrollview is set, however.
ex:
CGSize barfStringSize = [barfString sizeWithFont:[barf_ font]
constrainedToSize:CGSizeMake(barf_.bounds.size.width, MAXFLOAT)
lineBreakMode:UILineBreakModeWordWrap]
[barf_ setScrollEnabled:barfStringSize.height > barf_.bounds.size.height]

Remove padding on UITableViewCell

On a UITableViewCell with UITableViewCellStyleSubtitle styling, I'm setting the imageView.image, textLabel.text, and detailTextLabel.text. There's white padding all around the cell. How do I get rid of the padding so all my images touch each other like the Youtube app below?
Probably the easiest way to do this would be to subclass UITableViewCell and override the -layoutSubviews method to do something like this:
- (void)layoutSubviews {
//have the cell layout normally
[super layoutSubviews];
//get the bounding rectangle that defines the position and size of the image
CGRect imgFrame = [[self imageView] frame];
//anchor it to the top-left corner
imgFrame.origin = CGPointZero;
//change the height to be the height of the cell
imgFrame.size.height = [self frame].size.height;
//change the width to be the same as the height
imgFrame.size.width = imgFrame.size.height;
//set the imageView's frame (this will move+resize it)
[[self imageView] setFrame:imgFrame];
//reposition the other labels accordingly
}
Just remove table separator:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
In iOS8 you can set
tableView.layoutMargins = UIEdgeInsets.zero
in code, or from Interface Builder.
Try reducing the UITableView's row height in interface builder or code so that there is no padding.
I had to increase the padding i did so in the interface builder for the tableview.
However Daves answer might give you more control over modifying the cell view.

How to make a UITextView Expand with the text like the Notes app

How can you make a UITextView expand with the text that is inside of it?
you could try this...
UITextView *textView; // your UITextView
NSString *text; // the text that you want to place in the UITextView
UIFont *textViewFont; // the font that you are using for your UITextView
CGSize size = {255,2000.0f}; //The default width, and max height you want to use
CGSize newSize = [text sizeWithFont:textViewFont
constrainedToSize:size lineBreakMode:UILineBreakModeWordWrap];
textView.frame = CGRectMake(0,0,newSize.width, newSize.height);
You can try this..
CGRect frame = textView.frame;
frame.size.height = [textView contentSize].height;
textView.frame = frame;
Are you using UITextView inside UITableView?
Let's suppose you are using UITextView inside UITableView. In order to make UITextView height dynamic(As per the content inside it) we need to take care of following things:-
Make sure UITextView constraints are properly given. e.g: I had used XIB for tableview cell and inside cell I had a UITextView. So, I will give constraint to UITextView 0 to all four sides e.g: Top, bottom, leading, trailing. (Depends on your requirements).
Make sure UITextView attribute, autoscroll is disabled. It should be off.
Make sure TableView cell height is UITableView.automaticDimension
Now inside your 'textViewDidChange' delegate method, Just add this below mentioned code:
UIView.setAnimationsEnabled(false)
tableView?.beginUpdates()
tableView?.endUpdates()
UIView.setAnimationsEnabled(true)
Now your textView will auto expand, while you are typing init.