Ellipsis at the end of UITextView - iphone

If I have multi-line non-scrollable UITextView whose text is longer than can fit in the visible area, then the text just cuts off like so:
Congress shall make no law respecting
an establishment of religion, or
How would I get the text to show with an ellipsis where the text cut-off is, like so
Congress shall make no law respecting
an establishment of religion, or …
Other controls like labels and buttons have this ability.

Why not use a UILabel setting numberOfLines to something appropriate and getting that functionality for free?

The UITextView is designed to scroll when the string is larger than what the view can show. Make sure that you have set the anchoring and autoresize attributes correctly in code or your xib.
Here is an example from a blog post about how to implement your own ellipsis.
#interface NSString (TruncateToWidth)
- (NSString*)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font;
#end
#import "NSString+TruncateToWidth.h"
#define ellipsis #"…"
#implementation NSString (TruncateToWidth)
- (NSString*)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font
{
// Create copy that will be the returned result
NSMutableString *truncatedString = [[self mutableCopy] autorelease];
// Make sure string is longer than requested width
if ([self sizeWithFont:font].width > width)
{
// Accommodate for ellipsis we'll tack on the end
width -= [ellipsis sizeWithFont:font].width;
// Get range for last character in string
NSRange range = {truncatedString.length - 1, 1};
// Loop, deleting characters until string fits within width
while ([truncatedString sizeWithFont:font].width > width)
{
// Delete character at end
[truncatedString deleteCharactersInRange:range];
// Move back another character
range.location--;
}
// Append ellipsis
[truncatedString replaceCharactersInRange:range withString:ellipsis];
}
return truncatedString;
}
#end

Someone just showed me that it's actually really easy to do this with UITextView on iOS 7 and up:
UITextView *textView = [UITextView new];
textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;

Related

Remove dot from UITextField

I create on application and i required to enter price. client required its own design keyboard so i develop following keyboard. it works perfect . Problem is when the text is larger then UITextField's with then it display dots. I search on google and SO but not found any thing.
how to avoid dots next to a uitextfield
How to remove dots in UITextfield? and other answer but not working in my case. When I used default keyboard it scroll the text what i input number
My key board is
when length is greater then TextFied Width then it display
My code is
- (IBAction)numberPressed:(id)sender {
UIButton *btn=(UIButton *)sender;
int number=btn.tag;
if (number <= 9)
txtPrice.text = [NSString stringWithFormat:#"%#%d",txtPrice.text, number];
//decimal point
else if (number == 10) {
if ([txtPrice.text rangeOfString:#"."].location == NSNotFound)
txtPrice.text = [NSString stringWithFormat:#"%#.", txtPrice.text];
}
//0
else if (number == 11)
txtPrice.text = [NSString stringWithFormat:#"%#0", txtPrice.text];
//backspace
else if (number == 12) {
if ([txtPrice.text length] > 0)
txtPrice.text = [txtPrice.text substringToIndex:[txtPrice.text length] - 1];
else
txtPrice.text = #"";
}
}
#pragma mark -
#pragma mark -TextField Delegate Method
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[self showKeyboard];
return NO; // Hide both keyboard and blinking cursor.
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
return YES;
}
UITextField is specifically one-line only. So whatever the UITextField is big when it reach the end it will display dots.
You need to use UITextView instead of UITextField for display and editing of multiline text.
In Interface Builder add a UITextView where you want it and select the "editable" box. It will be multiline by default.
I think this will help you. ^_^
You can try this:
self.txtPrice.font = [UIFont systemFontOfSize: 14.0];
self.txtPrice.adjustsFontSizeToFitWidth = YES;
self.txtPrice.minimumFontSize = 7.0;
"adjustsFontSizeToFitWidth" is a Boolean value indicating whether the font size should be reduced in order to fit the text string into the text field’s bounding rectangle.
"minimumFontSize" is the size of the smallest permissible font with which to draw the text field’s text.
If you want a similar behavior as the calculator or the phone app you have to set the following property to true(YES):
textField.adjustsFontSizeToFitWidth = YES;
You should also set the minimumFontSize property to "to prevent the receiver from reducing the font size to the point where it is no longer legible."
Check out the UITextField Reference
Another approach is (Remove dot and clip text to frame)-
your can remove dot from UITextField calling following code
[self.yourTextField becomeFirstResponder];
you can also hide default keyboard [if you use any custom keyboard] using following code
// Hide keyboard for Dial Pad, but show blinking cursor
UIView *dummyKeyboardView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
yourTextField.inputView = dummyKeyboardView;
[dummyKeyboardView release];
But I think IlNero's answer is better for you if you want to show all text (does not clip).
What you can do is
txtPrice.text = [txtPrice.text stringByReplacingOccurrencesOfString:#"." withString:#""];
let me know it is working or not!!!
Happy Coding!!!

Is it possible to highlight a NSString or draw some color to a string

i am having this code to get the text between "." for example i am having lots of text like .1 this is first.2 this is second.3 this is fourth etc etc.when i tap the first ext it displays the first text in log .the code is
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[NSTimer scheduledTimerWithTimeInterval:0.001 target:maintextview selector:#selector(resignFirstResponder) userInfo:nil repeats:NO];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
NSRange selectedRange = [textView selectedRange];
NSString *backString = [maintextview.text substringToIndex:selectedRange.location];
NSRange backRange = [backString rangeOfString:#"." options:NSBackwardsSearch];
NSRange backRangee = [backString rangeOfString:#"." options:NSBackwardsSearch];
int myRangeLenght = backRangee.location - backRange.location;
NSRange myStringRange = NSMakeRange (backRange.location, myRangeLenght);
NSString *forwardString = [maintextview.text substringFromIndex:backRange.location];
NSLog(#"%#",[[forwardString componentsSeparatedByString:#"."] objectAtIndex:1]);
}
forwadString contains the tapped text,i just want to highlight this string or draw a color above this text using core graphics or something like that.is out possible?
thanks in advance
Much to my and many other's disappointment, Apple chose not to implement NSAttributedString until iOS 3.2, and even then, all standard UI elements are incapable of rendering them!
Luckily, the few, the proud, and the brave have answered the call and DTCoreText was born.
As for an actual selection, because UITextView conforms to UITextInput as of iOS 3.2, you can use and set the selectedTextRange.
It's impossible to 'colour' an NSString, a string is just a representation of characters, it holds no font, colour or style properties. Instead you need to colour the UI element that draws the text to the screen.
If forwardString is in a UILabel or UITextView you can colour the text inside these by setting the textColor property. For example if you had a UILabel called lbl you could set the colour by using:
lbl.textColor = [UIColor redColor];

Calculating enough text to fit within existing UILabel

I can't get some CoreText text wrapping code working for me; it's just too complicated. I'm going to try and go another route, which is to split my UILabel into two.
What I'm trying to achieve is to have my text appear to wrap around my fixed sized rectangular image. It'll always be the same dimensions.
So, when the UILabel next to the image fills up exactly, it'll create another UILabel below the image.
Now, how do I calculate the text in the first UILabel and have it fit nicely in the entire width of the UILabel, without being too short or cut off at the end?
Well, this ought to work to get the substring of the master string that will fit within the desired width:
//masterString is your long string that you're looking to break apart...
NSString *tempstring = masterString;
while (someLabel.bounds.size.width < [tempString sizeWithFont:someLabelLabel.font].width) {
NSMutableArray *tempArray = [NSMutableArray arrayWithArray:[tempString componentsSeparatedByString:#" "]];
//Remove the last object, which is the last word in the string...
[tempArray removeLastObject];
//Recreate the tempString with the last word removed by piecing the objects/words back together...
tempString = #"";
for (int i=0; i < tempArray.count - 1; i++) {
tempString = [tempString stringByAppendingFormat:#"%# ", [tempArray objectAtIndex:i]];
}
//You must append the last object in tempArray without the space, or you will get an infinite loop...
tempString = [tempString stringByAppendingFormat:#"%#", [tempArray objectAtIndex:tempArray.count - 1]];
}
//Now do whatever you want with the tempString, which will fit in the width desired...
Of course, this is assuming you want the separation to occur using word wrapping. If you don't mind words themselves being cut apart (i.e. character wrap) in order to fully take up the desired width, do this instead:
NSString *tempstring = masterString;
while (someLabel.bounds.size.width < [tempString sizeWithFont:someLabelLabel.font].width) {
tempString = [tempString substringToIndex:tempString.length - 1];
}
//Now do whatever you want with the tempString, which will fit in the width desired...
In order to get the remaining piece of the string left over, do this:
NSString *restOfString = [masterString substringFromIndex:tempString.length];
Hope this helps. I have to admit that I haven't properly tested this code yet, though I've done something similar in the past...
Try below link its will help you.
If you want to create a "link" on some custom text in your label, instead of using a WebView as #Fabian Kreiser suggested, you sould use my OHAttributedLabel class (you can find it this link)
See the sample code provided on my github repository: you can use my addCustomLink:inRange: method to add a link (with a customized URL) to a range of text (range that you could determine by iterating over every occurrences of the word "iPhone" in your text very easily). Then in the delegate method on OHAttributedLabel, you can catch when the link is tapped and act accordingly to do whatever you need.

UITextView how to cut off text

I have a UITextView that is displaying a facebook status loaded from Facebook Connect. I'm trying to make it so that the UITextView is just creating a preview of the text. I want it to look like it does when there is too much text for a UILabel. It would be something like "There is too much text..." with the dots but UITextViews don't do that. Does anybody know how to get it to work?
Write a separate method that counts how many letters there are in the string and if there are more than some preset value then cut it and append three dots to the end.
Also, consider using UILabels instead of UITextViews if you don't need to edit information inside since UITextViews take longer to allocate and init and are generally slower than UILabels.
+(NSString *)getTruncatedTextForString:(NSString *)inputString withFont:(UIFont *)font withLength:(int)textViewlength
{
CGSize dotSize=[#"..." sizeWithFont:font];
float dotWidth=dotSize.width;
NSString *outputString=#"";
int reqLength=textViewlength-dotWidth;
for(int i=0;i<inputString.length;i++)
{
NSString *tempStr=[outputString stringByAppendingString:[inputString substringWithRange:NSMakeRange(i,1)]];
if([tempStr sizeWithFont:font].width>reqLength)
{
break;
}
else
{
outputString=tempStr;
}
}
NSString *tempStr=[outputString stringByAppendingString:#"..."];
outputString=tempStr;
return outputString;
}
Try the below code. It will display two dots to the textview with text more than its frame height.
if(textview.contentSize.height > textview.frame.size.height)
{
while (textview.contentSize.height > textview.frame.size.height)
{
textview.text = [textview.text substringWithRange:NSMakeRange(0, textview.text.length-1)];
}
textview.text = [textview.text substringWithRange:NSMakeRange(0, textview.text.length-2)];
textview.text= [NSString stringWithFormat:#"%#..",textview.text];
}
It works, only when we set the correct height to the UITextview with respect to the font and fontsize of that textview.
For ex, if the font is bold system font of size 16 means, the textview height should be of minimum 30.

How to know the displayed text in UILabel?

I have an UIView containing two UILabels, in order to display a string.
The first UILabel has a fixed size, and if the string is too long and can't hold in this UILabel, I want to display the maximum characters I can in the first UILabel, and display the rest of the string in the second UILabel.
But to make this, I must know the exact part of the string displayed in the first UILabel, which is not easy because of the randomness of the string and the linebreaks.
So, is there a way to get just the text displayed in the first UILabel, without the truncated part of the string?
if ([_infoMedia.description length] > 270) {
NSRange labelLimit = [_infoMedia.description rangeOfString:#" " options:NSCaseInsensitiveSearch range:NSMakeRange(270, (_infoMedia.description.length - 270))];
_descTop.text = [_infoMedia.description substringToIndex:labelLimit.location];
_descBottom.text = [_infoMedia.description substringFromIndex:(labelLimit.location+1)];
} else {
_descTop.text = _infoMedia.description;
_descBottom.text = #"";
}
Okay that's a late answer but maybe it could help someone. The code above is approximatively the solution I used in my app.
_descTop is my first label and _descBottom is the second label. 270 is a constant equivalent to a little less than the average maximum number of characters displayed in my first label, _descTop. I calculated it by hand, trying with many different strings, maybe there's a better way to do that but this worked not bad.
If the string I want to display (_infoMedia.description) is larger than 270 characters, I isolate the first 270 characters plus the end of the next word in the string (by searching the next space), in the case where the 270 characters limit would cut the string in the middle of a word. Then I put the first part of the string in my first label, and the second part in the second label.
If not, I only put the globality of the string in the first label.
I know that's a crappy solution, but it worked and I didn't found any better way to do that.
Following code might help you in getting what you want!!
//If you want the string displayed in any given rect, use the following code..
#implementation NSString (displayedString)
//font- font of the text to be displayed
//size - Size in which we are displaying the text
-(NSString *) displayedString:(CGSize)size font:(UIFont *)font
{
NSString *written = #"";
int i = 0;
int currentWidth = 0;
NSString *nextSetOfString = #"";
while (1)
{
NSRange range;
range.location = i;
range.length = 1;
NSString *nextChar = [self substringWithRange:range];
nextSetOfString = [nextSetOfString stringByAppendingString:nextChar];
CGSize requiredSize = [nextSetOfString sizeWithFont:font constrainedToSize:CGSizeMake(NSIntegerMax, NSIntegerMax)];
currentWidth = requiredSize.width;
if(size.width >= currentWidth && size.height >= requiredSize.height)
{
written = [written stringByAppendingString:nextChar];
}
else
{
break;
}
i++;
}
return written;
}
#end