UITextView within UIScrollView - Dynamic Heights? - ios

I have a UIView which contains a UIScroller - which in turn contains a couple of labels, one image and a dynamic text view.
The text view can contain anything from a few characters to 2000 words - how can I automatically apply the relevant heights to the UITextView and the parent scroller?
I have got as far as the following -
//Set Scroller
[self.scrollerArticle setScrollEnabled:YES];
[self.scrollerArticle setContentSize:CGSizeMake(320, 750)];
[self.articleUITextView sizeToFit];
[self.articleUITextView layoutIfNeeded];
But don't know how to apply the sizetofit method to the scroller?

Try like this,
[self.scrollerArticle setContentSize:CGSizeMake(320, CGRectGetMaxY(self.articleUITextView.frame))];

UITextView is a subclass of UIScrollView and you should use content size after you set up a text to get the size:
self.articleUITextView.text = #"YOUR TEXT";
CGRect rec = self.articleUITextView.frame;
rec.size.height = self.articleUITextView.contentSize.height;
textView.frame = rec;
After that you can just chance contentSize of your scroll view.
If you want to use sizeWithFont: it works fine for UILabels but not necessary with UITextView.

You can get the height of the content using the below method.
-(CGFloat)getContentHeight{
NSString *aMessage = #"My Name is ABC"; // Can be anything between 0 to 2000 chars
CGSize maximumSize = CGSizeMake(320, 9999);
// Use the font you are willing to use for TexTView.
UIFont *textFont = [UIFont fontWithName:#"Helvetica-Bold" size:MessageFontSize];
CGSize myStringSize = [aMessage sizeWithFont:textFont
constrainedToSize:maximumSize
lineBreakMode:NSLineBreakByWordWrapping];
return myStringSize.height;
}
And then can set the ContentSize of Scrollview accordingly.

Related

iOS 8 sizeThatFits for UITextView text not returning correct height (AutoLayout)

I'm trying to vertically center a UITextView using the appropriate height retrieved from sizeThatFits. There are a plethora of other answers that suggest this is the most appropriate way of calculating this.
(Note that I've tried it both with plain and attributed strings, and both exert the same behavior).
No matter what I try (even using attributed strings and setting the font size or line height to something bigger or smaller) it always only shows a certain truncated number of characters of text (in this case, 3 lines, and it's always exactly the same). What am I missing?
_textView.text = [_collectionDescription lowercaseString];
_textView.font = [UIFont fontLight:22];
_textView.textColor = [UIColor whiteColor];
_textView.textAlignment = NSTextAlignmentCenter;
_constraintTextViewHeight.constant = ceilf([_textView sizeThatFits:CGSizeMake(_textView.frame.size.width, FLT_MAX)].height);
[_textView setNeedsDisplay];
[_textView updateConstraints];
As always with AutoLayout, you have to do:
[_textInfoView layoutIfNeeded];
(don't even need the setNeedsDisplay at all).
So, fully working:
_textView.text = [_collectionDescription lowercaseString];
_textView.font = [UIFont fontLight:22];
_textView.textColor = [UIColor whiteColor];
_textView.textAlignment = NSTextAlignmentCenter;
_constraintTextViewHeight.constant = ceilf([_textView sizeThatFits:CGSizeMake(_textView.frame.size.width, FLT_MAX)].height);
[_textView layoutIfNeeded];
[_textView updateConstraints];
Instead of using sizeThatFits: method, you may use following method:
well you can try this:
NSDictionary *attributes = #{NSFontAttributeName: [UIFont fontWithName:#"HelveticaNeue" size:14]};
// NSString class method: boundingRectWithSize:options:attributes:context is
// available only on ios7.0 sdk.
NSString *text = _textView.text;
CGRect rect = [text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
_constraintTextViewHeight.constant = CGRectGetHeight(rect)
This method also considers line breaks in string text

UILabel Size to fit is not working

This is what I'm doing. I'm not dynamically creating the label, just picking from the object library.it is working only if I statically increase the height of the label, but I doesn't know at runtime
[self.lblDescription setText:#"This is going to be a test description but a very big description that should increase in height"];
[self.lblDescription sizeToFit];
The label is not going on the next line. But instead it is clipping it as soon as the left of the label reaches the right of the screen
Based on the answers and I tried the following but didn't work:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.lblDescription setText:#"This is going to be a test description but a very big description that should increase in size"];
self.lblDescription.numberOfLines = 0;
[self.lblDescription sizeToFit];
}
I also tried setting -
[self.lblDescription setLineBreakMode:NSLineBreakByWordWrapping];
before calling [self.lblDescription sizeToFit]; but didn't work
Setting adjustsFontSizeToFitWidth property to true did it for me.
Try,
self.lblDescription.adjustsFontSizeToFitWidth = true
(by default it is set to false)
Check for the numberOfLines property
self.lblDescription.numberOfLines = 0;
EDIT : Need to change the height as well (By the comment says) .
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"Helvetica Neue" size:19], NSFontAttributeName,
nil];
CGRect expectedLabelFrame = [text boundingRectWithSize:CGSizeMake(571, 500)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributesDictionary
context:nil];
// Adjust the yourLabel the the new height.
CGRect newFrame = yourLabel.frame;
newFrame.size.height = expectedLabelFrame.size.height;
yourLabel.frame = newFrame;
I've found that when using sizeToFit with a UILabel, in InterfaceBuilder you need to change the Autoshrink property from 'Fixed Font Size' to 'Minimum Font Size'. I usually then set its value to 0.5 to be sure its working properly.

UIScrollView not scrollable using autolayout and dynamic constraints

I have a view which contains a scrollview, a containerview and 3 subviews (topview, textview and bottomview). See the view's hierachy below. The height of the textview is defined based on its content. I defined a dynamic constraint for its height and I change it in viewDidLayoutSubviews. The size of the textview is correct but the problem is that my scrollview is not scrolling. What I am doing wrong? Perhaps I need to add/modify some of the other constraints?
-(void)viewDidLayoutSubviews
{
NSAttributedString * string = [[NSAttributedString alloc] initWithString:self.game.description];
CGFloat heightTV = [self textViewHeightForAttributedText:string andWidth:260];
self.dynamicTVHeight.constant = heightTV;
[self.view layoutIfNeeded];
}
- (CGFloat)textViewHeightForAttributedText:(NSAttributedString *)text andWidth:(CGFloat)width
{
UITextView *textView = [[UITextView alloc] init];
[textView setAttributedText:text];
CGSize size = [textView sizeThatFits:CGSizeMake(width, FLT_MAX)];
return size.height;
}
The UIScrollView scroll only if it has contentSize bigger than bounds. Content size of UIScrollView can be set automatically by calculating frames of subviews (calculated from constraints) or manually in code (usually in viewDidLoad).
Double check your UIScrollView's contentSize.

Width of UILabel created programmatically

I'm trying to create a UILabel programmatically that fits it's content.
The best I could do was to use the NSString's method sizeWithAtributes to get it's content's required width and then apply a constraint that fixes the width to that value.
Is this the way it is supposed to be done using autolayout?
if you need some with aoutolayouts, i try comment:
UILabel *testLabel = [UILabel new];
[testLabel setFont:[UIFont systemFontOfSize:16]];
[testLabel setText:#"Test text for size context"];
[testLabel setTextAlignment:NSTextAlignmentLeft];
[testLabel setNumberOfLines:0]; //0 - infiniy lines if not enough space more
[testLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; // Autolayout rule: The higher the priority, the more important hold the text.. by horizontal
[testLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];//some like above but verticale
[testLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];// reverse like Hugging but Compression. then lower priority then text croping.
[testLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisVertical];
[testLabel preferredMaxLayoutWidth:200];//Start new line each 200 points width
[testLabel setPreferredMaxLayoutWidth:YES];// resize Font size by label size.
[testLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; // Disable autolaresize, enable autolayouts
At First read the best answer for any question about UILabel
And also by using following code you can create dynamic size of UILabel
UILabel *myLabelName = [[UILabel alloc] init];
myLabelName.backgroundColor = [UIColor redColor];
[myLabelName setFont: [UIFont fontWithName:#"OpenSans" size:13]]; // set font and it's size as per your requirement.
myLabelName.textAlignment = NSTextAlignmentLeft;
myLabelName.frame = CGRectMake(lblComplainTitle.frame.origin.x + lblComplainTitle.frame.size.width + 7, lblComplainTitle.frame.origin.y +2, 160, 20);
myLabelName.text = #"This is my testing text, This is my testing text, This is my testing text, This is my testing text, This is my testing text, This is my testing text, This is my testing text, This is my testing text, This is my testing text, This is my testing text.";
myLabelName.textColor = [UIColor blackColor];
[self setDynamicHeightOfLabel:myLabelName withLblWidth:160 andFontSize:13]; // here in this function you need to pass object of label with width (as you wabt) and font size
[self.view addSubview:myLabelName];
Code of function, name is setDynamicHeightOfLabel:withLblWidth:andFontSize
-(void) setDynamicHeightOfLabel:(UILabel *) myLabel withLblWidth:(CGFloat) width andFontSize:(int) fontSize
{
CGSize myLabelSize = CGSizeMake(width, FLT_MAX);
CGSize expecteingmyLabelSize = [myLabel.text sizeWithFont:myLabel.font constrainedToSize:myLabelSize lineBreakMode:myLabel.lineBreakMode];
CGRect lblFrame = myLabel.frame;
lblFrame.size.height = expecteingmyLabelSize.height;
myLabel.frame = lblFrame;
int addressLine = myLabel.frame.size.height/fontSize;
myLabel.numberOfLines = addressLine;
}
I create function because you can create any label with dynamic size without use of repeated code.
There is a couple of steps that you have to do to achieve this using autolayout.
Set layout constrains for the label.
Set height constraint with low priority.
Set numberOfLines to 0 to allow multiline text.
Set preferredMaxLayoutWidth for the label.
The preferredMaxLayoutWidth is used by label to calculate its height.
This property affects the size of the label when layout constraints
are applied to it. During layout, if the text extends beyond the width
specified by this property, the additional text is flowed to one or
more new lines, thereby increasing the height of the label.
Hi you can manage the width of lable by doing so programatically,
CGRect frame;
frame =self.yourLabel.frame;
frame.size.width +=20;
self.yourLabel.frame=frame;
Thanks

Changing an embedded UITextView width on rotation?

I have a UITextView embedded inside a grouped table view cell that I can't seem to update on rotation. It basically keeps the same width (assumed portrait) when it becomes landscape, causing about 40% of the view to be blank on the left side.
Is there a way to update this easily? I was looking at willRotateToInterfaceOrientation but I wasn't sure if that was the right thing to update the view on rotation.
Specifically, I'm thinking the width value should be updated, since it's based on the width.
if (indexPath.section == 1) {
switch (indexPath.row) {
case 0:
{
NSString *label = [self.pedal detail];
CGFloat width = [UIScreen mainScreen].bounds.size.width * .95;
CGSize stringSize = [label sizeWithFont:[UIFont systemFontOfSize:15]
constrainedToSize:CGSizeMake(320, 9999)
lineBreakMode:UILineBreakModeWordWrap];
UITextView *textField = [[UITextView alloc] init];
[textField setFrame:CGRectMake(50,0, width-10, stringSize.height+55)];
[textField setEditable:NO];
textField.backgroundColor = [UIColor clearColor];
textField.font = [UIFont systemFontOfSize:15];
textField.textAlignment = UITextAlignmentLeft;
cell.accessoryView = textField;
textField.text = [self.pedal detail];
[textField release];
break;
}
}
}
You need to set textField.autoresizingMask = UIViewAutoresizingFlexibleWidth, which streches the object on its width on view size change.
Read more at the UIView documentation
You have tried setting the sizing properties in IB right? The way the object scales and what points are anchors should be able to be set there.

Resources