limit the UILabel to 500 character and than Truncate the UIlabel in IOS - iphone

I want to display first 500 character in UILabel and than display Truncate icon if there is more than 500 character available.But i dont know how can i limit 500 character to truncate the text?.
Here is my code
label2 = [[UILabel alloc] initWithFrame:CGRectMake(0, 350, self.bounds.size.width, 30)];
// In this case value of self.bounds.size.width is "427"
label2.backgroundColor = [UIColor clearColor];
label2.numberOfLines = 2;
label2.textAlignment = UITextAlignmentCenter;
label2.font = [UIFont systemFontOfSize:13];
[self addSubview:label2]
//Here is Implimentation code of my label
NSString *temp = [galleryEntryTree objectForKey:#"description"];// calling lebel text from database
coverView.label2.text = temp;
coverView.label2.adjustsFontSizeToFitWidth = NO;
coverView.label2.lineBreakMode = UILineBreakModeTailTruncation;
Just tell me guys how can i display min 500 character and than truncate it( if longer than 500)
Any help is appreciated

Just truncate the string if it's longer than 500 characters. Only caveat: make sure to not break it in the middle of a surrogate pair:
NSString *temp = [galleryEntryTree objectForKey:#"description"];
if ([temp length] > 500) {
NSRange range = [temp rangeOfComposedCharacterSequencesForRange:(NSRange){0, 500}];
temp = [temp substringWithRange:range];
temp = [temp stringByAppendingString:#" …"];
}
coverView.label2.text = temp;

To display only 500 character just use below code:
NSString *string = YOUR_TEXT;
if ([string length] >500) {
string = [string substringToIndex:500];
}
Hope this will help you.
All the best !!!

Here is how to do it in Swift 2.2:
let maxLength = 500
if originalString.characters.count > maxLength {
let range = originalString.rangeOfComposedCharacterSequencesForRange(Range<String.Index>(originalString.startIndex ..< originalString.startIndex.advancedBy(maxLength)))
let tmpValue = originalString.substringWithRange(range).stringByAppendingString(" …")
// use tmpValue
}

try this one it'l helps you.
label2 = [[UILabel alloc] initWithFrame:CGRectMake(0, 350, self.bounds.size.width, 30)];
// In this case value of self.bounds.size.width is "427"
label2.text=#"your text................................";
if([label2.text length]>500)
label2.text=[label2.text substringToIndex:500];
label2.backgroundColor = [UIColor clearColor];
label2.numberOfLines = 2;
label2.textAlignment = UITextAlignmentCenter;
label2.font = [UIFont systemFontOfSize:13];
[self addSubview:label2]

It can be simply done by
NSString *LabelNewText = [YourLabelName.text substringToIndex:500];
Here 500 or less than 500 characters will be displayed and all the characters exceeding that will be truncated.
NSString *string = LabelNewText.text;
if ([string length] >500)
{
string = [string substringToIndex:500];
}

Swift 3.0 version
let maxLength = 300 //char length
if originalString.characters.count > maxLength {
let range = originalString.rangeOfComposedCharacterSequences(for: originalString.startIndex..<originalString.index(originalString.startIndex, offsetBy: maxLength))
let tmpValue = originalString.substring(with: range).appending("...")
}

Related

UILabel is not displaying its correct value even if it is giving the newly assigned value in console

I have a UILabel which is displayed as a question. Its successfully displaying the question text which has been assigned to it programmatically. But later according to one if else condition, I have to change text in the label.Specifically I want to display an asterik(*) mark at the end of the string if that is a mandatory question.The * should be in red color and rest of the text should be in black.But it displays only the question not the * mark.If I try to print the questLabel.text it is giving the question with * mark at the end.Here is the code that I am trying
questText = questLabel.text;
questText = [questText stringByAppendingString:#"✶"];
NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:questText];
NSMutableAttributedString *text =
[[NSMutableAttributedString alloc]
initWithAttributedString: str];
int length = (int)text.length;
[text addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:NSMakeRange(length-1, 1)];
[questLabel setAttributedText: text];
If I try to print the value of questLabel.attributedText :
Question{
}✶{
NSColor = "UIDeviceRGBColorSpace 1 0 0 1";
}
And the value for questLabel.text is :Question✶
Please help me out with this..Thanks in advance..
You should change your code to this.
NSString *questText = questLabel.text;
questText = [questText stringByAppendingString:#"✶"];
NSMutableAttributedString *text =
[[NSMutableAttributedString alloc] initWithString:questText];
int length = (int)text.length;
[text addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, length-1)];
[text addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(length-1, 1)];
[questLabel setAttributedText: text];
You can also try this
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self.questLabel.text attributes:#{NSForegroundColorAttributeName:[UIColor blackColor]}];
NSMutableAttributedString *starString = [[NSMutableAttributedString alloc] initWithString:#"✶" attributes:#{NSForegroundColorAttributeName:[UIColor redColor]}];
[string appendAttributedString:starString];
[self.questLabel setAttributedText:string];

Is it possible to select the first line of a UILabel?

I have a UILabel with the parameter numberOfLines set to 2. I would like to make 2 UIlabels from this one, the first one would be the first line and the second will be the second line. Is there any way to make it?
In this solution, I've assumed that you have UILabel with 2 line at least, and there is a \n character at the end of the first line.
UILabel *lbl = (UILabel *)[self.view viewWithTag:2];
NSString *firstString;
NSString *secondString;
NSRange foundRange = [lbl.text rangeOfString:#"\n"];
if (foundRange.location != NSNotFound)
{
foundRange.length = foundRange.location + 1;
foundRange.location = 0;
firstString = [[NSString alloc] initWithString:[lbl.text substringWithRange:foundRange]];
secondString = [[NSString alloc] initWithString:[lbl.text stringByReplacingCharactersInRange:foundRange withString:#""]];
NSLog(#"first line = %#", firstString);
NSLog(#"second line = %#", secondString);
[firstString release];
[secondString release];
}

Access last line while using UILineBreakModeWordWrap UILabel in iPhone

I am displaying a long string using UILabel with UILineBreakModeWordWrap. It is showing the string perfectly by wrapping text in UILabel. I want to access last line of UILabel. Does anyone know how to do this on an iPhone?
So I tried some stuff and searched a little around. What you wuld actually need is to count the word wraps and somehow detect the last string. But I didnt really figuere out how to do that.
So my sollution is something like this:
Your String //I googled some longer String
NSString *string = #"Standing across the room, I saw you smile\nSaid I want to talk to you-oo-oo for a little while\nBut before I make my move my emotions start running wild\nMy tongue gets tied and that's no lie\nLooking in your eyes\nLooking in you big brown eyes ooh yeah\nAnd I've got this to say to you\nHey!\nGirl I want to make you sweat\nSweat till you can't sweat no more\nAnd if you cry out\nI'm gonna push it some, more, more\nGirl I want to make you sweat\nSweat till you can't sweat no more\nAnd if you cry out\nI'm gonna push it\nPush it, push it some more";
Your Label:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 440)];
label.font = [UIFont fontWithName:#"Helvetica" size:14];
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor blackColor];
label.text = string;
The call this Method:
NSString *result = [self getLastLineFromString:string];
NSLog(#"Result: %#", result);
getLastLineFromString: looks like this:
- (NSString *)getLastLineFromString: (NSString *)string{
NSArray *a = [string componentsSeparatedByString:#" "];
NSString *result = [a objectAtIndex:[a count]-1];
NSString *temp = #"";
int count = 1;
BOOL myBool = YES;
while (myBool) {
count++;
temp = result;
result = [a objectAtIndex:[a count] -count];
result = [NSString stringWithFormat:#"%# %#", result, temp];
NSLog(#"length: %i",[self lengthOfString:result]);
NSLog(#"result: %#",result);
//131 was a value i detected mayels, i guess u have do trick a little around to find a mathcing one for yourself
if ([self lengthOfString:result] >= 131) {
myBool = NO;
}
}
return result;
}
And The MethodlengthOfString: looks like this:
- (int)lengthOfString:(NSString *)string{
CGSize size1 = [string sizeWithFont:[UIFont fontWithName:#"Helvetica" size:14]];
return size1.width;
}
Output:
2012-01-06 16:17:08.341 get length[5472:207] result: it
Push it, push it some more
I know this is not a perfect sollution, but it might help you.

Accurately and seamlessly splitting text into two UILabels

I'm trying to create a "wrapping" like effect for text around an image that has set dimensions.
___________
........|
........| image
label.1.|
........|___________
....................
.......label.2......
....................
....................
Here is the method im using right now:
- (NSArray *)splitString:(NSString*)str maxCharacters:(NSInteger)maxLength { //this will split the string to add to two UILabels
NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:1];
NSArray *wordArray = [str componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSInteger numberOfWords = [wordArray count];
NSInteger index = 0;
NSInteger lengthOfNextWord = 0;
while (index < numberOfWords) {
NSMutableString *line = [NSMutableString stringWithCapacity:1];
while ((([line length] + lengthOfNextWord + 1) <= maxLength) && (index < numberOfWords)) {
lengthOfNextWord = [[wordArray objectAtIndex:index] length];
[line appendString:[wordArray objectAtIndex:index]];
index++;
if (index < numberOfWords) {
[line appendString:#" "];
}
}
[tempArray addObject:line];
}
return tempArray;
}
I give it the maxCharacters value of where I want to split the text, which is the max height of the first UILabel. This method is essentially what I want, but sometimes the last line of the first UILabel is "higher" than others leaving a gap between the first UILabel and the second UILabel.
Here is how I use the method:
NSArray *splitStringArray = [self splitString:eventRecord.summary maxCharacters:280];
UILabel *firstSumValue = [[UILabel alloc] init];
NSString *firstSumString = [splitStringArray objectAtIndex:0];
CGSize maxFirstSumSize = CGSizeMake(185.0,150.0);
UIFont *firstSumFont = [UIFont fontWithName:#"HelveticaNeue-Bold" size:12];
CGSize firstSumStringSize = [firstSumString sizeWithFont:firstSumFont
constrainedToSize:maxFirstSumSize
lineBreakMode:firstSumValue.lineBreakMode];
CGRect firstSumFrame = CGRectMake(10.0, presentedValue.frame.origin.y + presentedValue.frame.size.height, 185.0, firstSumStringSize.height);
firstSumValue.frame = firstSumFrame;
firstSumValue.font = [UIFont fontWithName:#"HelveticaNeue" size:12];
firstSumValue.lineBreakMode = UILineBreakModeWordWrap;
firstSumValue.numberOfLines = 0 ;
[self.mainScrollView addSubview:firstSumValue];
firstSumValue.text = [splitStringArray objectAtIndex:0];
UILabel *secondSumValue = [[UILabel alloc] init];
NSInteger isSecond = 0; //no
if([splitStringArray count] > 1){
isSecond = 1; //yes
NSString *secondSumString = [splitStringArray objectAtIndex:1];
CGSize maxSecondSumSize = CGSizeMake(310.0,9999.0);
UIFont *secondSumFont = [UIFont fontWithName:#"HelveticaNeue-Bold" size:12];
CGSize secondSumStringSize = [secondSumString sizeWithFont:secondSumFont
constrainedToSize:maxSecondSumSize
lineBreakMode:secondSumValue.lineBreakMode];
CGRect secondSumFrame = CGRectMake(10.0, firstSumValue.frame.origin.y + firstSumValue.frame.size.height, 310.0, secondSumStringSize.height);
secondSumValue.frame = secondSumFrame;
secondSumValue.font = [UIFont fontWithName:#"HelveticaNeue" size:12];
secondSumValue.lineBreakMode = UILineBreakModeWordWrap;
secondSumValue.numberOfLines = 0 ;
[self.mainScrollView addSubview:secondSumValue];
secondSumValue.text = [splitStringArray objectAtIndex:1];
}
How do I keep everything consistent and aligned properly. Perhaps, there is a better method one could recommend. Not core text because it's out of my scope of knowledge.
Consider using a UIWebView instead, with the layout defined in a local HTML file. It can save you a lot of headache rather than trying to deal with complex layouts by hand.

Objects added as subview to scrollview are not showing up

I am trying to add elements to a scroll view using this code:
int missionCount;
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSDictionary *missionsDict = [responseString JSONValue];
/*NSArray *luckyNumbers = [json objectWithString:responseString error:&error];*/
NSLog(#"user Info array is: %#", missionsDict);
// NSDictionary *array = [luckyNumbers1 objectForKey:#"data"];
NSDictionary *missionsData;
missionsData = [missionsDict objectForKey:#"data"];
NSLog(#"missionsData is: %#", missionsData);
NSEnumerator *inner = [missionsData objectEnumerator];
missionsScroll.contentSize = CGSizeMake(768, 1005);
id value;
int badgeY1;
int badgeY2;
int badgeY3;
badgeY1 = 146;
badgeY2 = 188;
badgeY3 = 188;
while((value = [inner nextObject])) {
NSLog(#"value is: %#", value);
NSLog(#"progress is: %#", [value objectForKey:#"progress"]);
NSLog(#"user Info array is: %#", missionsDict);
NSLog(#"name is: %#",[value objectForKey:#"reward_definitions"]);
NSLog(#"missionsData is: %#", missionsData);
NSDictionary *moreData;
moreData = [value objectForKey:#"reward_definitions"];
NSEnumerator *inner2 = [moreData objectEnumerator];
id value2;
int badgeX;
int badgeCount;
badgeX = 0;
badgeCount = 0;
while((value2 = [inner2 nextObject])) {
UIProgressView *progressView;
progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(323, badgeY1, 372, 9)];
float progressValue;
progressValue = ([[[value objectForKey:#"progress"] objectForKey:#"earned"] floatValue] / [[[value objectForKey:#"progress"] objectForKey:#"possible"] floatValue]);
NSLog(#"progressValue is: %f", progressValue);
[progressView setProgress:progressValue];
[missionsScroll addSubview:progressView];
UILabel *missionName;
missionName = [[UILabel alloc] initWithFrame:CGRectMake(66, badgeY1, 227, 21)];
missionName.backgroundColor = [UIColor clearColor];
missionName.textColor = [UIColor whiteColor];
missionName.font = [UIFont fontWithName:#"Heiti TC" size:23.0];
missionName.text = [value objectForKey:#"name"];
[missionsScroll addSubview:missionName];
UILabel *requirementsLabel;
requirementsLabel = [[UILabel alloc] initWithFrame:CGRectMake(66, badgeY2+25, 227, 21)];
requirementsLabel.backgroundColor = [UIColor clearColor];
requirementsLabel.textColor = [UIColor whiteColor];
requirementsLabel.font = [UIFont fontWithName:#"Papyrus" size:19];
requirementsLabel.text = #"To complete you need:";
[missionsScroll addSubview:requirementsLabel];
NSLog(#"Image URL is: %#", [value2 objectForKey:#"image_url"]);
NSURL *url1 = [NSURL URLWithString: [NSString stringWithFormat:#"%#", [value2 objectForKey:#"image_url"]]];
NSData *urlData1 = [NSData dataWithContentsOfURL:url1];
UIImage *image1 = [UIImage imageWithData:urlData1];
UIImageView *badge = [[UIImageView alloc] initWithImage:image1];
[badge setFrame:CGRectMake(badgeX, badgeY2+70, 70, 70)];
[missionsScroll addSubview:badge];
[badge release];
badgeCount = badgeCount+1;
NSLog(#"badgeCount is: %i", badgeCount);
if (badgeCount == 4) {
NSLog(#"Badge Count = 4");
badgeY2 = badgeY2 +70;
badgeX = 0;
badgeCount = 0;
} else {
NSLog(#"Badge Count ≠ 4");
badgeX = badgeX +75;
}
}
NSLog(#"1st While loop done");
// NSLog(#"reward_definitions is: %#", [missionsData objectForKey:#"id"]);
// NSLog(#"Image URL is: %#", [[value objectForKey:#"reward_definitions"] objectForKey:#"image_url"]);
//if ( [array isKindOfClass:[NSDictionary class]] ) {
badgeY1 = badgeY1 +200;
badgeY2 = badgeY2 +200;
badgeY3 = badgeY3 +200;
missionCount = missionCount+1;
}
NSLog(#"While loops done");
for (int a; missionCount > 4; a = a+1) {
missionsScroll.contentSize = CGSizeMake(776, missionsScroll.contentSize.height+200);
}
Nothing is showing up in the scroll view.
It's not obvious what is happening, but first things to check are where the views are valid (not nil) and that this code is running on the main thread.
Put these in and post the results.
NSLog(#"missionsScroll: %#", (missionsScroll==nil)?#"NIL":#"OK");
NSLog(#"progressView: %#", (progressView==nil)?#"NIL":#"OK");
NSLog(#"missionName: %#", (missionName==nil)?#"NIL":#"OK");
NSLog(#"mainThread: %#", ([NSThread isMainThread])?#"OK":#"Background Thread");
Your code is quite convoluted and very difficult to read. Perhaps you could check if your complicated coordinates calculations work as expected, e.g.
NSLog(#"Frame of badge %#", NSStringFromCGRect(badge.frame));
How many times are your while loops iterating? The outer loop increases the y-position of your labels. But the labels will only be displayed at the end of the run loop / start of the next run loop. If you exit this method with the labels with a high y-value then you'll not see them. (It doesn't matter how many times you change the y-value while you're running this code. The display will only update when it's all done.)
** Correction ** You seem to be adding new views each time around your while loop. So in fact I'd expect you to have multiple copies of the subviews appearing when they finally get displayed.
(There's a lot of code to wade through here. If my answer is way off, you might get better answers, but trimming back some of the code and isolating the issue.)