Dynamically change UILabel width not work with autolayout - ios

I have some code:
CGRect currentFrame = textLabel.frame;
CGSize max = CGSizeMake(textLabel.frame.size.width, 3000);
CGSize expected = [[textLabel text] sizeWithFont:textLabel.font constrainedToSize:max lineBreakMode:textLabel.lineBreakMode];
currentFrame.size.height = expected.height;
textLabel.frame = currentFrame;
expected.height = expected.height + 70;
[scrollView setContentSize:expected];
textLabel placed inside UIScrollView to display multiline text information.
In older version of application, without 4-inch screen support, everything was perfect.
But now, unfortunately, resizing UILabel does not work.
Maybe, somebody can advice me, what should I change?
Thanks.

When using AutoLayout you should not update the frame property, instead modify the contraints on a view.
On the other hand, you could also let AutoLayout work for you. Make sure the numberOfLines property of the label is set to 0 and the height constraint is of type Greater Than or Equal (>=). This way the layout will update automatically after setting new text on a label.

Related

Make background UILabel bigger

I have a question in my app I have a number label (IBOutlet). And when I write self.numberLabel.backgroundColor = [UIColor redColor]; is showing a red color fit in the height of number, All I want is to make the background a little bit bigger. Thanks
self.numberLabel.frame = CGRectMake(self.numberLabel.frame.origin.x, self.numberLabel.frame.origin.y, widht, newHeight);
and to make sure font stay same size if needed
[self.numberLabel setFont:[UIFont systemFontOfSize:35]];
You have to set constraints in Interface Builder / Storyboard to fix your label height/width.
If your label's content changes in width, you can use this to calculate a new width with a bit of space left:
float labelWidth =
[self.myLabel.text
boundingRectWithSize:self.myLabel.frame.size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{ NSFontAttributeName:self.myLabel.font }
context:nil]
.size.width;
CGRect rect = self.myLabel.bounds;
rect.size.width = labelWidth + 15.0f; //replace 15.0F with the value you want
[self.myLabel setBounds:rect];
There're many ways to skin a cat... in my case the content of the "uilabel" determines its size. I just want the background to be slightly bigger -- 5 points vertically, 7 points horizontally. So I use autolayout to solve it.
Add a uilabel as a subview to the background which is a uiview
Add constraints in IB between the uilabel and the uiview
Add constraints in IB between the uiview and its superview

Create non-constant width for UILabel in Interface Builder using Auto Layout

I have an existing UILabel that I created in Interface Builder, I would like to change its width in code, but I can't because of the auto layout. It's pretty simple, I have width from a CGSize and I wanna set it for the label. Actually my code works perfectly, I can assign the new size to the label, but unfortunately it doesn't redrawn itself. I've tried to use the textRectForBounds:limitedToNumberOfLines:and preferredMaxLayoutWidth without any success or size changes.
float heightIs =
[cell.lbl.text
boundingRectWithSize:cell.lbl.frame.size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{ NSFontAttributeName:cell.lbl.font }
context:nil]
.size.height;
// get the width size of a string
CGSize textSize = [cell.lbl.text sizeWithAttributes:#{NSFontAttributeName:cell.lbl.font}];
CGFloat strikeWidth = textSize.width;
NSLog(#"TEXT WIDTH %f OF STRING %#", strikeWidth, nameString);
CGRect labelFrame = CGRectMake (0, 0, strikeWidth, heightIs);
cell.lbl.frame = labelFrame;
cell.lbl.preferredMaxLayoutWidth = CGRectGetWidth(labelFrame);
NSLog(#"LABEL WIDTH VALUE %f", cell.lbl.frame.size.width);
Could somebody explain me the right way? I'm not sure that where should I start it. Is it an option somewhere in IB or can I do it with code? Or I can delete all code because it can be done only with IB?

iOS7 UITextView scrollEnabled=YES height

I am doing a test project, and came across a problem with UITextView.
I am dynamically getting the content size of the text in the text view, and then increasing its height when needed. When the height reaches the threshold I have set, I will set scrollEnabled = YES to enable scrolling. Weird thing seems to happen as shown in the following screen shots:
Before going to new line and enabling scrolling:
After entering the next character, which will enable the scrolling:
After that, entering another character again, the text view will become normal again with scroll enabled (in fact the height remains as in the previous screen shot, I change the height according to content size, so it become the same height before enable scroll):
Anyone has came across this problem and able to solve it? If this is an iOS7 bug, any other suggestion for creating a message input text box? I wonder if previous iOS versions have this problem though.
Edited:
It seems like this problem occurs when the textview's scrollEnabled is YES and change the textview.frame.size.height, then the height will reset to the initial height (as in the height set in Interface Builder). Wonder if this will help for this problem.
The following shows the code used for editing the height of the text view (it is a method for the selector which will be called upon received UITextViewTextDidChangeNotification):
NSInteger maxInputFieldWidth = self.inputTextField.frame.size.width;
CGSize maxSize = CGSizeMake(maxInputFieldWidth, 9999);
CGSize neededSize = [self.inputTextField sizeThatFits:maxSize];
NSInteger neededHeight = neededSize.height;
if (self.inputTextField.hasText)
{
[self.inputTextField scrollRangeToVisible:NSMakeRange([self.inputTextField.text length], 0)];
if (neededHeight <= TEXTVIEW_MAX_HEIGHT_IN_USE && neededHeight != previousHeight)
{
previousHeight = neededHeight;
CGRect inputTextFieldFrame = self.inputTextField.frame;
inputTextFieldFrame.size.height = neededHeight;
inputTextFieldFrame.origin.y = TEXTVIEW_ORIGIN_Y;
self.inputTextField.frame = inputTextFieldFrame;
}
else if (neededSize.height > TEXTVIEW_MAX_HEIGHT_IN_USE)
{
if (!self.inputTextField.scrollEnabled)
{
self.inputTextField.scrollEnabled = YES;
CGRect inputTextFieldFrame = self.inputTextField.frame;
inputTextFieldFrame.size.height = TEXTVIEW_MAX_HEIGHT_IN_USE;
inputTextFieldFrame.origin.y = TEXTVIEW_ORIGIN_Y;
self.inputTextField.frame = inputTextFieldFrame;
}
else if (neededHeight != previousHeight)
{
previousHeight = neededHeight;
CGRect inputTextFieldFrame = self.inputTextField.frame;
inputTextFieldFrame.size.height = TEXTVIEW_MAX_HEIGHT_IN_USE;
inputTextFieldFrame.origin.y = TEXTVIEW_ORIGIN_Y;
self.inputTextField.frame = inputTextFieldFrame;
}
}
}
Over a year later and scrollEnabled is still causing problems. I had a similar issue where setting scrollEnabled = true (I'm using Swift) would not cause any changes.
I solved the problem by setting autolayout constraints on all sides of the textView. Then, like you detailed here, I just set textView.frame again. My guess is that this causes some internal update, which actually turns scrolling on. I'm also guessing that autolayout then forces the textView to stay at the right height, as opposed to the collapse that you're experiencing.
The brilliant Pete Steinberger has had a lot of problems with the UITextView and implemented a lot of fixes as a result.
His article can be found here with links to his code.
For a direct link to the code, it can be found here, but I recommend reading the post.
I ran into a similar issue (I'm using auto-layout) and was able to solve it with the following set up:
Adding top, leading, bottom, trailing margin constraints to my text view
Adding a greater-than-or-equal-to minimum height constraint with priority 999 (in my case this was set to 50)
Adding a less-than-or-equal-to maximum height constraint with priority 1000 (in my case this was set to 125)
Adding an equal-to height constraint with priority 1000 (set to 125) and making sure it's not installed (uncheck the 'installed' option in Interface Builder or set 'active' to NO/false on the constraint in code)
I then use the following code to determine the height of the text view and enable/disable scroll and constraints:
- (void)textViewDidChange:(UITextView *)textView {
...
CGSize size = textView.bounds.size;
CGSize newSize = [textView sizeThatFits:CGSizeMake(size.width, CGFLOAT_MAX)];
if (newSize.height >= self.textViewMaxHeightConstraint.constant
&& !textView.scrollEnabled) {
textView.scrollEnabled = YES;
self.textViewHeightConstraint.active = YES;
} else if (newSize.height < self.textViewMaxHeightConstraint.constant
&& textView.scrollEnabled) {
textView.scrollEnabled = NO;
self.textViewHeightConstraint.active = NO;
}
...
}
Using sizeThatFits: to determine the desired size of the text view, I either set scroll enabled or disabled. If it's enabled, I set the height constraint to active to force the text view to stay at the desired height.

How to resize the width of the UITextView according the?

I want to ask how to resize the UITextView to fit the text will display on the screen.
For example
Resize the UITextView to
Could anyone help me out or give me some advise.
Thanks
Tips:
I tried
sizeWithFont:constrainedToSize: ,Not work
If you need to know the CGSize that is taken by your NSString if rendered on a single line, use CGSize sz = [textView.text sizeWithFont:_textView.font] then adjust your frame given this size value.
If you need to know the size taken by your text if rendered on multiple lines, wrapping it if the text reaches a given width, use sizeWithFont:constrainedToSize:lineBreakMode: instead, etc.
I had the same problem some time ago (but with the height of the UITextView) and I created a CGRect with a size that would fit the contentSize of the UITextView, Try the code below
// assuming that you have a UITextView named textView with some text on it
CGRect textFrame = self.textView.frame;
textFrame.size.width = self.textView.contentSize.width;
self.textView.frame = textFrame;
try this one it worked for me
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
frame.size.width = _textView.contentSize.width;
_textView.frame = frame;
happy coding....

sizeToFit doesn't trigger new line with long words

I just ran into to strange problem, I have a custom tableview cell with a dynamic height.
While testing this all seemed to work fine, but now that I'm loading real content into it there seem to be some problems.
It appears that some text doesn't trigger a new line in a UILabel
Correct: http://dl.dropbox.com/u/274185/Screen%20Shot%202012-05-09%20at%201.15.21%20PM.png
Wrong: http://dl.dropbox.com/u/274185/Screen%20Shot%202012-05-09%20at%201.15.30%20PM.png
As you can see in the wrong example, the text is pushed to the second line, but the height of the label still only counts one line.
item.project = #"Another Test Project With Longer Title (Admin / Project Management)";
item.project = #"Test Project (Admin / Project Management)";
The way I calculate the height is like this:
// when creating the cell
cell.projectLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.projectLabel.numberOfLines = 0;
[cell.projectLabel sizeToFit];
// in heightForRowAtIndexPath()
CGSize projectHeight = [item.project sizeWithFont:[UIFont boldSystemFontOfSize:13.0f] constrainedToSize:CGSizeMake(320.0f, CGFLOAT_MAX) lineBreakMode: UILineBreakModeWordWrap];
I tried changing the lineBreakMode, but this doesn't seem to help much
EDIT:
It appeared to be a problem when calculation the height of the text, I used a fixed 320 points, which isn't correct, after using the actual width the height was calculated correctly.
CGSize projectHeight = [item.project sizeWithFont:[UIFont boldSystemFontOfSize:13.0f] constrainedToSize:CGSizeMake(cell.projectLabel.bounds.size.width, CGFLOAT_MAX) lineBreakMode: UILineBreakModeWordWrap];
I believe that sizeToFit only sizes the view down.
You should set the frame of your label to be high enough for two lines and then call sizeToFit. That will shrink the label when the text is only one line but keep its height when the text is two lines.

Resources