Objective-C: Evenly displaying NSStrings - objective-c

If I am looping through a bunch of strings and want to say use them as the stringValue of a NSTextField or title of a NSButton programmatically is there a way to determine the length I will need for the frame of the textfield or buttons and the spacing between...I know this is kind of relevant to the font selected for each but it would be great if I could dynamically figure out NSString.length = x pixels. Any thoughts?

Look into the sizeWithFont method on NSString.
CGSize size = [mystring sizeWithFont:myfont];
CGSize has a height and width that you can then examine.

Related

How to enlarge UILabel width (letter spacing) in Objective-C?

This is the code I am using for the UILabel title of my View Controller:
UIFont *bebasFont = [UIFont fontWithName:#"Bebas" size:100];
RestaurantsTitle.font = bebasFont;
RestaurantsTitle.text = #"RESTAURANTS";
and I need to enlarge the space between the letters of the title but I don't know how to do it.
Setting a width to the text field and not the frame would also work if that is also possible?
I need to enlarge the space between the letters
Use NSAttributedString and increase the kerning of the string.
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSAttributedString_Class/index.html
https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSAttributedString_UIKit_Additions/index.html#//apple_ref/doc/c_ref/NSKernAttributeName

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;

How to fit a text with various length in a UITableViewCell?

What I have is:
a NSString which can have any length between 1 and 400 characters
a UITableViewCell (custom layout)
I tried using an UILabel with multiple lines, set the text, and call sizeToFit. That doesn't work always, most of the time the UILabel just clips off the part of the string that doesn't fit. Also, due the varying length of the text I'd need differently sized UITableViewCells, and at the time "tableView: cellForRowAtIndexPath:" is called I don't know what the height will be.
So what I need is a non-scrolling UI element which is able to display text and resizes its height (the width should remain constant) to exactly fit the text. As mentioned the sizeToFit method produces mostly garbage.
You can use SizeWithFont: to calculate the desired height for your cell and store it in an Array so that you can return that height in HeightForRowAtIndexPath. If you need to update the text, just have a method that re-calculates the height, saves it to the array, and updates the table. Something like:
CGSize constraintSize;
constraintSize.width = 290.0f;
constraintSize.height = MAXFLOAT;
NSString *text = #"YOUR TEXT"
CGSize theSize = [text sizeWithFont:[UIFont systemFontOfSize:15.0f] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
NSLog(#"height: %f",theSize.height);
will give you the height.
This configuration should give you something simillar to what you see when you enter a loooong number in the phone app -
label.minimumFontSize = 4; //a very small font size
label.adjustsFontSizeToFitWidth = YES;
label.lineBreakMode = UILineBreakModeWordWrap;// change to what works for you
label.numberOfLines = 0;
See lineBreakMode Documentation

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!

What is the best way to implement a variable-sized multi-line UITableCell?

I'm trying to display a table full of twitter statuses (yes, this is the Stanford Presence 2 assignment), which are variably sized. I can relatively easily determine the appropriate height for my rows with code that approximates (from accompanying lecture 9):
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *) indexPath
{
NSString *text = ...;
UIFont *font = [UIFont systemFontOfSize:...];
CGSize withinSize = CGSizeMake(tableView.width, 1000];
CGSize size = [text sizeWithFont:font constrainedToSize:withinSize lineBreakMode:UILineBreakModeWordWrap];
return size.height + somePadding;
}
I have tried two approaches (and some tweaks to both) to get a multi-line word-wrapping field of text into my table row.
Add a UILabel as a subview to my custom UITableCell subclass, and set the numberOfLines property to either a calculated number based on the height above (say, 6), or to 0 (theoretically unlimited). The numberOfLines is ignored; I see either 1 or 2 lines, and no more.
Add a read-only UITextView as a subview. This has the problem that the UITextView eats my scrolling; I end up scrolling inside a UITextView row instead of moving smoothly from row to row. If I disable scrolling on the UITextView, I end up being unable to scroll at all.
This is a pretty common thing to do; what's the best way to accomplish it?
You might want to look at the userInteractionEnabled property of the UITextView. That should allow input to be passed through to the UITableView so you get scrolling.
Here's a link to a blog I posted on this subject. I used a UILabel with numberOfLInes = 0. I hope this will be of some help.
Sample Project with Variable Sized UITableViewCell
While playing with userInteractionEnabled=NO, scrollEnabled=NO, and getting the right autosizing parameters set in IB worked, I think that going with a UILabel with numberOfLines=0 and the same autosizing parameters is ultimately a better idea, for the next person.