sizeWithFont:constrainedToSize doesn't work with custom font - objective-c

I'm trying to resize a UITextView to the size the text within it.
The problem is that Im using a custom font and it the text doesnt fit within the UITextView.
NSString *textToFit = #"pretty long text";
UIFont *customFont = [UIFont fontWithName:#"Museo-100" size:15];
CGSize sizeText = [textToFit sizeWithFont:customFont constrainedToSize:CGSizeMake(textFrame.size.width, 1000)];
Where textFrame is the frame of the UITextView I want to adjust its height.
Im trying different fonts and also different files of the same font and still it never adjusts its height to the height that the text fills.
I've been searching and I dont find a solution. I've tried a workaround using a UILabel and the method textRectForBounds, but still no success, something on this lines.
UILabel *auxLabel = [[UILabel alloc]init];
auxLabel.numberOfLines = 0;
auxLabel.font = [UIFont fontWithName:#"Museo-100" size:15];
auxLabel.text = //THE TEXT I WANT TO FIT IN
CGRect textSize = CGRectMake(0.0, 0.0, textDescription.frame.size.width, FLT_MAX);
CGRect frame = [auxLabel textRectForBounds:textSize limitedToNumberOfLines:0];

I think
UIView : sizeToFit
Should solve your problem.
sizeToFit Resizes and moves the receiver view so it just encloses its
subviews.
Discussion: Call this method when you want to resize the current view so that it uses the most appropriate amount of space.
Specific UIKit views resize themselves according to their own internal
needs. In some cases, if a view does not have a superview, it may size
itself to the screen bounds. Thus, if you want a given view to size
itself to its parent view, you should add it to the parent view before
calling this method.
https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html#//apple_ref/occ/instm/UIView/sizeToFit

Related

UIScrollView won't adjust height to fit subviews

I have a UITextView, which sets its text dynamically from an RSS feed. The textview is a subview of a UIScrollview. Ultimately, I am creating a mobile newspaper app, so the user should be able to scroll through the text (and other subviews).
After creating the views in IB, I added
NSString *sourceCode = [NSString stringWithContentsOfURL:[NSURL URLWithString:self.URL] encoding:NSUTF8StringEncoding error:&error];
sourceCode = [self parseHTMLText:sourceCode];
CGSize maximumLabelSize = CGSizeMake(320,9999);
CGSize txtStringSize = [sourceCode sizeWithFont:self.body.font
constrainedToSize:maximumLabelSize];
CGRect newlblFrame = CGRectMake(0, 0, 320, txtStringSize.height);
self.body.frame = newlblFrame; //body is the textview
self.body.text = sourceCode;
self.scroll.contentSize=CGSizeMake(320, self.body.frame.size.height+300); //scroll is scrollview
A typical NSLog will display body frame = {{0, 0}, {320, 2088}} scrollview frame = {{0, 0}, {320, 417}} scrollview content size = {320, 2388}
However, when I run the app, body maintains its interface builder height of around 196 and the scrollview won't scroll (when i move it, it just bounces back to its original position)
On a side note, when I try to manually change the frame of the textview with CGRectMake, the NSLog shows the correct height, but the view doesn't appear different. I made sure that it's hooked up correctly in IB, because I can adjust other properties, like background color.
EDIT:
After I set the cliptoBounds property of the textview to NO, the textview now adjusts its height and tries to show the entire text. However, it cuts off at the end of the screen, and I still cannot scroll.
Here is what I see currently. I made the scrollview background color gray for convenience. I'm not sure why part of the scrollview is partially in white and and partially gray. (Title) is a separate label btw)
I fixed the problem by moving the code from viewDidLoad to viewDidAppear. Apparently this is an Xcode 4.5 specific issue, resulting from the AutoLayout feature overriding the logic in the viewDidLoad method. A better explanation can be found here.
i hope this will help you
self.scrollview.contentSize=CGSizeMake(320, label.frame.size.height+30);
Try to add this :
[_scrollView setClipsToBounds:YES];
Try this:
CGSize maximumSize = CGSizeMake(200.0, 30.0); // Specify your size. It was for my screen.
UIFont *txtFont = <Ur Font size & Var>;
//new
//fontValue = txtFont;
//new
lblValue.font = txtFont;
lblValue.lineBreakMode = UILineBreakModeWordWrap;
CGSize txtStringSize = [commentTxt sizeWithFont:txtFont
constrainedToSize:maximumSize
lineBreakMode:lblValue.lineBreakMode];
CGRect newlblFrame = CGRectMake(105.0, y, 200.0, txtStringSize.height);
lblValue.frame = newlblFrame;
lblValue.text = #"Your String";
After this set scroll Content size. Hope it'll work for you. It worked for me.
Try to solve in the following way.
// adjust the height of UITextView with content height
CGRect frame = self.body.frame;
frame.size.height = self.body.contentSize.height;
self.body.frame = frame;
// adjust UIScrollView's height with the height of UITextView
self.scroll.frame = frame;

UITextView size for UITableViewCell

I have a tableview, one of the rows contains a cell that contains a UITextView. I need to know the size of the textview because I need it to fit the cell and return that size in 'heightForRowAtIndexPath' method. Using the NSString method for size only works for labels, not for textviews. What are my options?
Thanks
Does the UITextView already have the proper size, or do you need to resize it as well to exactly contain its text? There are no out-of-the-box methods to do that I believe.
If it already has the proper size, you can just get the height from its frame:
CGRect frame = textView.frame;
CGSize size = frame.size;
CGFloat = size.height;

Setting the UITextView height to fit the content height in Objective c

I have the code as below for my UITextView set up.
CGRect itemDescFrame = CGRectMake(20, 160, 280, 200);
UITextView *itemDesc = [[UITextView alloc] initWithFrame:itemDescFrame];
...
itemDesc.editable = NO;
itemDesc.scrollEnabled = NO;
...
I have disabled the UITextView scroll bar, however some of the content on the bottom is being hidden. How can I set the UITextView height to fit to the content height?
Thanks
UPDATE:
NSLog(#"frame %#", itemDesc.frame.size.height);
NSLog(#"content %#", itemDesc.contentSize.height);
Result:
2011-10-11 11:00:18.010 abc[1606:207] frame 200.000000
2011-10-11 11:00:18.010 abc[1606:207] content 200.000000
As a subclass of UIScrollView, UITextView has a property called contentSize which, in the case of a UITextView, should be the size that the text occupies after it is is placed in the view. Try setting the height of the text view's frame to the height of contentSize.
Simply add this line of code to force the frame to update its size based on the height of the text it contains:
[self.myTextView sizeToFit];
Note that if you want to add additional padding you can set textContainerInset.
You'll want to call that when the text content changes and upon rotation. To make it easy to see the height adjust, set a background color on the UITextView.

How to make height of OHAttributedLabel scale with content height?

I use an OHAttributedLabel called demoLbl for displaying text with formatted areas. This label is laid out with Interface Builder and is connected to a property in my ViewController. After setting the attributedText to the label I want all the text to be displayed in the label.
If I don't resize the label then the text is cropped at the end of the label so the rest of the text is missing.
If I use [demoLbl sizeToFit]; then the height of the label is larger or smaller in height than the text (about 10 point, varying with the text's length) thus giving me blank areas at the bottom of my view (after scrolling) plus the width of the label is increased by about 2 points.
If I calculate the height of the original text (NSString) before putting it in a NSAttributedString and adding it to the label's attributedText property then the calculated height is way too small for setting it as the label's height.
Is there a hack or trick I can apply so that the label's height is adjusted according to the NSAttributedString's height?
PS: To be more specific I wanted to add OHAttributedLabel as a tag but it's not allowed to me yet.
I'm the author of OHattributedLabel.
I made some fixes recently about my computation of the size. Please check it out it will probably solve your issue.
I also added a method named sizeConstrainedToSize:fitRange: in NSAttributedString+Attributes.h that returns the CGSize of a given NSAttributedString (quite the same way UIKit's sizeWithFont:constrainedToSize: works, but for Attributed strings and CoreText and not plain stings an UIKit)
Actually OHAttributedLabel's sizeThatFits: calls this method itself now.
You can see if this category gives you a more reliable height.
https://gist.github.com/1071565
Usage
attrLabel.frame.size.height = [attrLabel.attributedString boundingHeightForWidth:attrLabel.frame.size.width];
I added this code to the implementation of the OHAttributedLabel class:
// Toni Soler - 02/09/2011
// Overridden of the UILabel::sizeToFit method
- (void)sizeToFit
{
// Do not call the standard method of the UILabel class, this resizes the frame incorrectly
//[super sizeToFit];
CGSize constraint = CGSizeMake(self.frame.size.width, 20000.0f);
CGRect frame = self.frame;
frame.size = [self sizeThatFits:constraint];
[self setFrame:frame];
}
// End Toni Soler - 02/09/2011
Thank you Olivier for sharing your code!

How to mask a UILabel in iOS - Objective-C

I want to sub-class a UIView and place four UILabels over top one another ; top label will be the MASK, 2nd label will be a normal label with text, the 3rd label is a label with solid background with no text. the bottom label will the same as the top 2nd label with a different color font. when i sent the width of the third label it will cover up the bottom label showing a partial view of the text. I want to have the 2nd text be one color while the uncoverd bottom label display another color font.
Is this possibe? If someone can explain how to mask in objective-C that will help too.
I trying to build a UIView that acts like a progress bar, as the bar fill to 60%, I want to top text to show in white font color, when the bottom text shows in a different color.
You could do it with two UILabels, one on the bottom, and one embedded in another view on top.
UILabel *bottomLabel = ...;
[self.view addSubview:bottomLabel];
UIView *topContainer = [[UIView alloc] initWithFrame:bottomLabel.frame];
topContainer.clipsToBounds = YES;
topContainer.opaque = NO;
topContainer.backgroundColor = [UIColor clearColor];
UILabel *topLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, bottomLabel.frame.size.width, bottomLabel.frame.size.height)];
topLabel.text = bottomLabel.text;
topLabel.opaque = NO;
topLabel.backgroundColor = [UIColor clearColor];
[topContainer addSubview:topLabel];
[self.view addSubview:topContainer];
Then, when you want to change the progress, you'd set the width of topContainer. This should clip topLabel.
Rather than using four UILabels, why not subclass UILabel and draw it yourself in the drawRect: method? It would look something like:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// Set the mask
CGContextClipToMask(context, self.bounds, /* mask image */);
// Draw the text in a different font
[self.text drawInRect:rect withFont:/* alternate font */];
// Draw a solid background
CGContextSetRGBFillColor(context, ...);
CGContextFillRect(context, rect);
// Draw the text normally
[super drawRect:rect];
}
You could make the masking image and the alternate font properties of your subclass, for convenience.