I did a lot of research but none helped with my current situation. What I want to do is have an auto resizing UITextView that grows as the user types. It starts off with a default height and auto grows as the text increases. I added to UITextView to my UIView using the interface builder. now I just need help with making it auto grow. The answers I found said in IOS7 you use [myTextView sizeToFit] which makes it auto-resize but looks like this only works for UITextViews that are added programmatically.
I made a subclass of UITextView just for that:
https://github.com/MatejBalantic/MBAutoGrowingTextView
It is an auto-layout based light-weight UITextView subclass which automatically grows and shrinks based on the size of user input and can be constrained by maximal and minimal height - all without a single line of code.
Made primarily for use in Interface builder and only works with Auto layout.
You will need to set a delegate for myTextView and have it respond to changes in its text.
In your view controller's interface declare that it conforms to the UITextViewDelegate protocol, e.g.:
#interface MyViewController : UIViewController <UITextViewDelegate>
In your view controller's -viewDidLoad add this:
self.myTextView.delegate = self;
Then implement the -textViewDidChange: delegate method:
- (void)textViewDidChange:(UITextView *)textView
{
if (textView != self.myTextView)
return;
CGFloat const horizontalPadding = 16.0f; // experiment with these padding values
CGFloat const verticalPadding = 16.0f; // until the textview resizes nicely
CGSize maxSize = CGSizeMake(textView.bounds.size.width - horizontalPadding, CGFLOAT_MAX);
CGSize textSize;
if ([textView.text respondsToSelector:#selector(sizeWithAttributes:)]) {
// iOS7 and above
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSValue valueWithCGSize:maxSize], NSViewSizeDocumentAttribute,
textView.font, NSFontAttributeName, nil];
textSize = [textView.text sizeWithAttributes:attributes];
} else {
// iOS6 and below
textSize = [textView.text sizeWithFont:textView.font
constrainedToSize:maxSize
lineBreakMode:NSLineBreakByWordWrapping];
}
CGRect newFrame = textView.frame;
newFrame.size.height = textSize.height + verticalPadding;
textView.frame = newFrame;
}
I would suggest you try HPGrowingTextView before using a custom solution.
In case you do not like it, you would go about it like this:
Create a UITextView with an initial frame and add it to a UIView.
Override the textViewDidChange: method and get a CGSize of the content using yourTextView.contentSize property.
Use the height property of this CGSize to set the height of your UITextView using CGRectMake.
The contentSize gives you the exact size of the content in your textView, without using sizeWithFont:(deprecated) or sizeWithAttributes:.
But here's the catch: If your textView is contained inside another UIView, you might have to set it's autoresizingMasks to UIViewAutoresizingFlexibleTopMargin, UIViewAutoresizingFlexibleBottomMargin, UIViewAutoresizingFlexibleHeight as per your need, for the succesful resizing of superviews of the textView.
Try going through the code of HPGrowingTextView, and you will understand how this behaviour is implemented.
Related
How get UITextView contentView height, if Iam using sizeToFit property ?
if you are using,
int numLines = txtview.contentSize.height / txtview.font.lineHeight;
to get the number of lines in the textView then you don't need sizeToFit or not required to set textView's frame as per content size.
txtview.contentSize.height will give you content view's height and you can get number of lines.
But make sure that you are doing this in viewDidAppear(or any where after your view is appeared) not in viewDidload because in viewDidload your textview is not loaded completely.
UITextView itself has a function called sizeThatFits: which will return the smallest size needed to display all contents of the UITextView inside a bounding box, that you can specify.
The following will work equally for both iOS 7 and older versions and as of right now does not include any methods, that are deprecated.
- (CGFloat)textViewHeightForAttributedText: (NSAttributedString*)text andWidth: (CGFloat)width {
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setAttributedText : text];
CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];
return size.height;
}
Reference link UITableViewCell with UITextView height in iOS 7?
Situation
I have a (vertical) UIStackView containing both a plain UIView of height 50 (named sliderView) and a UILabel of height 36 defined in my storyboard. The label's alpha property is initially set to 0.0 to make it invisible.
In the controller's viewDidLoad I use UIViewController Containment to add another view controller's view to as a subview of sliderView. This new subview does not necessarily match sliderViews height. It might actually a fair bit taller.
At first, this setup looks fine. Once I make the label visible, I see that it still starts at a y-position of 50. So, the sliderView did not automatically stretch to use it's new child's height. Makes sense.
Question
I thought that I could easily just call sizeToFit on sliderView to make those two heights fit. Unfortunately, this does not seem to work. Am I misunderstanding something here? Thanks!
Use following method to get the CGSize required for NSString text.
- (CGSize)getHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font {
CGSize size = CGSizeZero;
if (text) {
CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{ NSFontAttributeName:font } context:nil];
size = CGSizeMake(frame.size.width, frame.size.height+20.0f);
}
return size;
}
Here width parameter is the width of your label and font is the font specified for your label. Call CGSize.height to get the height.
I have a label in custom cell in table view.
I want to change cell height and also label height(at first I am showing only 2 line, I want to show more text) after user taped a cell,
I am able to change cell height based on cell content, but unfortunately I cannot change label height, :((
I've read tons of stackoverflow answers, but still nothing.
it is believed that this would work:
CGSize labelSize = [#"Hello World!" sizeWithFont:[UIFont systemFontOfSize:17] constrainedToSize:CGSizeMake(label.frame.size.width,MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];
but this is deprecated in iOS 7; can any one please help me in resizing my label in cell?
If you want the height of your label relative to the height of your cell and you use Storyboard, you should determine the size of your label with constraints in relation to the ContentView of the cell. Just set the top and bottom distance from your label to the ContentView and no additional height for the label.
If you dont know how to set Storyboard and constraints, this might help: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html
UITableViewCell lays out it's content in -layoutSubviews. Therefore, if you want to simply have a custom layout logic, you need to subclass UITableViewCell and override the -layoutSubviews method. It's a good idea to call super anyway before applying your logic, though.
You may use something like this to get UIlabel size
-(CGFloat)getLabelSize:(UILabel *)label fontSize:(NSInteger)fontSize
{
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont systemFontOfSize:fontSize], NSFontAttributeName,
nil];
CGRect frame = [label.text boundingRectWithSize:CGSizeMake(270, 2000.0)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributesDictionary
context:nil];
CGSize size = frame.size;
return size.height;
}
I'm pretty new to ios. And while writing my first app i'v encountered that autolayout is only for ios 6.0. And i'd wish to make my app for at least 5.0 ios.
Maybe anyone would know how to make this without autolayout.
I have label which has dynamic text, 1row or 2 rows or 3 rows depends on user settings. And below it i have uitextfield. With autolayout i have no headache as it does all the work, the textfield sits nicely below in 1 2 or 3 rows of text above (resizes, moves automatically).
So how should i do this without autolayout?
Without autolayout you have to handle this in code. The recommended way of doing this would be to subclass your container view (the view that contains your label and text filed) and override the layoutSubviews method. In there you set the frames of the view's subviews manually, based on your desired criteria (e.g., the label text metrics).
EDIT: here's a specific example of something that could be in the containverView layoutSubviews method (typed from the top of my head):
// Those could be IBOutlets, or obtained by inspecting self.subviews
UILabel *label = self.label;
UITextField *textField = self.textField;
// Determine the labelSize, we could limit the maxSize (especially the height) manually here
CGSize maxSize = self.bounds.size;
CGSize labelSize = [label.text sizeWithFont:label.font constrainedToSize:maxSize lineBreakMode:label.lineBreakMode];
// Set the computed label size
CGRect labelFrame = label.frame;
labelFrame.size = labelSize;
label.frame = labelFrame;
// Now move the textField just below the label (we could also add a vertical margin here if we want)
CGRect textFieldFrame = textField.frame;
textFieldFrame.origin.y = labelFrame.origin.y + labelFrame.size.height;
textField.frame = textFieldFrame;
This just makes sure the text field is always below the label. Depending on the constraints you had in place, you might need to add more code to make sure the UI lays out correctly.
You also need to make sure that [containverView setNeedsLayout] gets called when the label text changes.
if you are using nib or storybord you can just remove the mark in the file inspector
I have a simple textView who's data gets populated dynamically. I want to resize the height of the textview once the data is populated so that i dont see a vertical scroll nor the text gets clipped.
Could it be done simply by choosing one of those textView modes or do i need to do it programaticaaly?
You can do this by adding these few lines of code to your application's:-
CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;
textView.frame = frame;
Implement this code in th delegate method of textview
- (void)textViewDidChange:(UITextView *)textView
{
// you might have to compare the frames if it needs changing as user might not have added an extra line
}
You have to do it programmatically. Use the NSString UIKit Additions to calculate the height of your UITextView:
sizeWithFont:
sizeWithFont:constrainedToSize:
sizeWithFont:constrainedToSize:lineBreakMode:
sizeWithFont:forWidth:lineBreakMode:
sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: