UILabel not getting what I write to it - ios

Tricky to write the subject to this. I guess this is a basic question but I can't seem to find the answer.
The code itself shows what I wanna do and the UILabel don't show anything, the first line I add to it works fine, but not when I try to write out the array:
-(IBAction)getSongHistory:(id)sender {
[historyLabel setText:#"test write\n test write another line"];
NSArray *pastMusicArray = [pastSongs getHistory];
for(int t=2; t<[pastMusicArray count]; t++) {
NSString *tempRow = [pastMusicArray objectAtIndex:t];
//NSLog(#"%#", tempRow);
[historyLabel setText:tempRow];
[historyLabel setText:#"\n"];
}
}
The NSLog do put out the right stuff.
What is gong on here, that I am not seeing?

Seems to me that the problem is that you are setting the full text each time and the last setText: is with #"\n" which is an invisible string. Try appending instead of setting the text. Something like:
historyLabel.text = [NSString stringWithFormat:#"%#%#", historyLabel.text,#"TextToAppend"];
This will append #"TextToAppend" to the current text value in the label.
Update: Notice I'm using the text property rather than the setter.
historyLabel.text = #"Some Text";
is equivalent to
[historyLabel setText:#"Some Text"];

Using \n in a string should be fine, try to set numberOfLines property of the label to 0, which allow any number of lines in it.

This is the solution for my own problem. Hope that it can help someone else.
NSArray *pastMusicArray = [pastSongs getHistory];
musicHistory = [[NSMutableString alloc] init];
historyLabel.numberOfLines = 0;
for(int t=2; t<[pastMusicArray count]; t++) {
[musicHistory appendString:[[pastMusicArray objectAtIndex:t] capitalizedString]];
[musicHistory appendString:#"\n"];
}
historyLabel.text = musicHistory;

Related

How to create a custom software key UITextField/NSTextField

I want to create a custom NSTextField/UITextField like this for entering a software key (pardon my paint skills).
Does anybody have any suggestions as to how I should go about this?
My lazy solution would be to give it a placeholder string with spaces and dashes in between, and as they type just mask those dashes into their string. But I wanted to see if anybody else had some input-- or if I should just go with your standard separate text fields
-(void)viewDidLoad
{
UITextField *firstPart = [[UITextField alloc] initWithFrame: YOUR_FRAME];
firstPart.placeholder = #"-";
firstPart.textAlignment = NSTextAlignmentCenter;
[self.view addSubview: firstPart];
// Create others
}
-(IBAction)unlockBtnPressed:(id)sender
{
NSString *softwareKey = [NSString stringWithFormat: #"%# - %# - %#", firstPart.text, secondPart.text, thirdPart.text];
}

NSMutableAttributedString will not display attribute that begins at nonzero index

UPDATE:
I created a really simple standalone project to demonstrate the bug. If anyone would like to pull same and see if they can spot where I've gone wrong, I'd sure appreciate it. There's not much code to look through. Public repo here:
https://github.com/reidnez/NSAttributedStringBugDemo
I'm having a very strange issue here: I have a tableview. Each cell has a title label with 1-3 words, and a keywords label with several CSV keywords. I also have a search bar. The requirement is that as the user types into the search bar, any partial matches on both the title and keywords for each cell are shown highlighted. Screenshots:
First image is A-Okay. In the second image, the "an" of the title label should be highlighted. But, as you can see, not so much...
This works perfectly fine on the "keywords" label, as you can see above. The attributed strings for both of these labels are created by a category I wrote (code below). The same method is called on both strings, and appears to behave the same from what the debugger is telling me. The UI tells a different story.
I have stepped through the debugger numerous times, and in all cases, the attributed string appears to have been configured correctly. I have also verified that something else is not calling [tableView reloadData] and that no other place in my code is overwriting the label's value. This is how matching on "an" for "Fang" looks in the debugger, just before the cell is returned at the end of cellForRowAtIndexPath:
(lldb) po customCell.entryTitleLabel.attributedText
F{
}an{
NSBackgroundColor = "UIDeviceRGBColorSpace 0.533333 0.835294 0.156863 1";
}g{
}
Looks good to me...that is exactly what I want. But when the cell renders, there are NO highlights to be seen! Weirder yet, as an experiment I tried setting the label to a completely arbitrary attributedString that I created right in cellForRow:
NSMutableAttributedString *fake = [[NSMutableAttributedString alloc] initWithString:#"Fang"];
[fake addAttribute:NSBackgroundColorAttributeName value:MATCH_TEXT_HILIGHT_COLOR range:NSMakeRange(1, 2)];
customCell.entryTitleLabel.attributedText = fake;
This, too fails. No highlighting at all...but I CAN highlight any substring in the range of {0, 1} to {0, fake.length} and it behaves as expected. Again, it seemingly refuses to highlight any substring that does not begin at index 0--but only for the title label.
Am I losing my mind? What am I missing?
Below is my category...but I am fairly confident the problem does not lie here, because it functions perfectly for the keywords string, and (again) the attributes appear to be set correctly just before the cell returns:
-(void)hilightMatchingSubstring:(NSString*)substring color:(UIColor*)hilightColor range:(NSRange)range
{
if ([self.string compare:substring options:NSCaseInsensitiveSearch] == NSOrderedSame) {
[self addAttribute:NSBackgroundColorAttributeName value:hilightColor range:NSMakeRange(0, self.length)];
return;
}
// Sanity check. Make sure a valid range has been passed so that we don't get out-of-bounds crashes. Default to return self wrapped in an attributed string with no attributes.
NSRange selfRange = NSMakeRange(0, self.length);
if (NSIntersectionRange(selfRange, range).length == 0) {
NSLog(#" \n\n\n*** Match range {%lu, %lu} does not intersect main string's range {%lu, %lu}. Aborting *** \n\n\n", (unsigned long)range.location, (unsigned long)range.length, (unsigned long)selfRange.location, (unsigned long)selfRange.length);
return;
}
if (substring.length > 0) {
NSRange movingRange = NSMakeRange(range.location, substring.length);
if (NSMaxRange(movingRange) > self.length) {
return;
}
NSString *movingString = [self.string substringWithRange:movingRange];
while (NSMaxRange(movingRange) < NSMaxRange(range)) {
if ([movingString compare:substring options:NSCaseInsensitiveSearch] == NSOrderedSame) {
[self addAttribute:NSBackgroundColorAttributeName value:hilightColor range:movingRange];
}
movingRange = NSMakeRange(movingRange.location + 1, substring.length);
movingString = [self.string substringWithRange:movingRange];
}
} // This is fine...string leaves properly attributed.
}
Thanks for writing this up... Thought I was going crazy too!
I came up with a workaround (read: hack) whilst we wait for something official from Apple.
NSDictionary *hackAttribute = [NSDictionary dictionaryWithObjectsAndKeys:
[UIColor clearColor], NSBackgroundColorAttributeName, nil];
NSMutableAttributedString *attributedText =
[[NSMutableAttributedString alloc] initWithString:#"some text..."];
[attributedAddressText setAttributes:hackAttribute range:NSMakeRange(0, attributedText.length)];
// Then set your other attributes as per normal
Hope that helps.

Old RPG scrolling text, but break up text blocks with (dot dot dot)

In old RPGs, the dialogue text would type on screen, and if there was more than could fit on the page there'd be a ... and you'd press to NEXT to continue reading.
I've got a lot of this already working. What I'm stuck on is I need a block of text to programmatically know how to break itself up from page to page using the ...
Normally, the easy route would be to just specify in the dialogue where the breaks should be, but for this specific project I have to allow it to take in a large block of text, then break it into the correct sizes for each page.
Anyone have any thoughts on how to do this? Just counting characters won't work because the font won't be monospaced.
I was having a hell of a time trying to search for this. Found this, but it didn't answer my question.
Much appreciated!
One solution could be:
separate all the words from the big text into an array
go through of it and search for the boundaries based on textbox height
You can implement it eg.:
CGFloat w = 200.0; // RPG textbox width. Get it from actual UI object.
CGFloat h = 150.0; // RPG textbox height. Get it from actual UI object.
NSArray *words = [yourRPGtext componentsSeparatedByString:#" "];
NSString *cur_txt = [words objectAtIndex:0];
int i = 1;
RPG_txt_pages = [[NSMutableArray alloc] init];
while (i < [words count]) {
NSString *next_txt = [cur_txt stringByAppendingFormat:#" %#",[words objectAtIndex:i]];
CGSize size = [next_txt sizeWithFont:yourRPGtextlable.font
constrainedToSize:CGSizeMake(w, 99999)
lineBreakMode:UILineBreakModeWordWrap];
if (size.height > h) {
cur_txt = [cur_txt stringByAppendingString:#"..."];
[RPG_txt_pages addObject:cur_txt];
cur_txt = [words objectAtIndex:i];
} else {
cur_txt = next_txt;
}
i++;
}
[RPG_txt_pages addObject:curText];
The key here is NSString's sizeWithFont method: here is the link to the docs.
IOS7 comment: sizeWithFont is deprecated you can use sizeWithAttributes. Here is an SO answer on this.
If you tell what IOS version are you using I'll modify this answer. Hope it helped!

Displaying Array in Text Label

I'm still sort of new to Xcode, so please be patient with me. Anyway, I'm having a bit of trouble trying to display the whole contents of an array in a UILabel. I'm able to display it by simply using the code
wordList.text = [NSString stringWithFormat:#"List of Words:\n %#", listA];
However upon running, the label ends up displaying a parenthesis and the words on their own lines, as well as quotation marks around the words, and the ending quotation mark and a comma in the line between each word. Example:
List of Words:
(
"apple
",
"banana
",
"etc.
While I do want the words to be displayed in their own lines, I do not want the parenthesis and the closing quotation mark and comma being displayed in a separate line. I would also prefer removing the parenthesis, quotation marks, and commas all together, but I wouldn't mind too much if I'm unable to.
Could anyone please explain why its being displayed as such, and to help me correctly display each word of an array in its own line in a UILabel?
Use this:
NSArray *listOfWords = #[#"One", #"Two", #"Three"];
NSString * stringToDisplay = [listOfWords componentsJoinedByString:#"\n"];
wordList.text = stringToDisplay;
Will Display:
One
Two
Three
The parentheses, quotation marks, and commas are being added because providing an array as an argument to the format specifier %# causes the -(NSString *)description method to be sent to the array. NSArray overrides NSObject's implementation of description and returns a string that represents the contents of the array, formatted as a property list. (As opposed to just returning a string with the array's memory address.) Hence, the extra characters.
You Can use this Code
NSArray *listOfWords = [NSArray arrayWithObjects:
#"one.",
#"two.",
nil];
for (NSString *stringToDisplay in matters)
{
//frame, setting
labelFrame.origin.x = 20.0f;
UILabel *stringToDisplayLabel = [[UILabel alloc] initWithFrame:labelFrame];
stringToDisplayLabel.backgroundColor = [UIColor clearColor];
stringToDisplayLabel.font = [UIFont boldSystemFontOfSize:12.0f];
stringToDisplayLabel.lineBreakMode = NSLineBreakByWordWrapping;
stringToDisplayLabel.numberOfLines = 0;
stringToDisplayLabel.textColor = [UIColor whiteColor];
stringToDisplayLabel.textAlignment = NSTextAlignmentLeft;
//set up text
stringToDisplayLabel.text = stringToDisplay;
//edit frame
[stringToDisplayLabel sizeToFit];
labelFrame.origin.y += stringToDisplayLabel.frame.size.height + 10.0f;
[self.view addSubview:stringToDisplayLabel];
[matterLabel release];
}

Change size of text in UITextView based on content of NSString

I am trying to load a UITextView with content from instances of a NSManagedObject subclass (verses in a Bible reader app).
My UITextView is loaded by iterating through the verses in a selected chapter and appending each consecutive verse.
NSArray *selectedVerses = [[Store sharedStore] versesForBookName:selectedBook
ChapterNumber:selectedChapterNum];
displayString = #"";
for (Verse *v in selectedVerses) {
NSMutableString *addedString =
[NSMutableString stringWithFormat:#"%d %#", [v versenum], [v verse]];
displayString = [NSMutableString stringWithFormat:#"%# %#", addedString, displayString];
}
NSString *title = [NSString stringWithFormat:#"%# %#", selectedBook, selectedChapter];
[self setTitle:title];
[[self readerTextView] setNeedsDisplay];
[[self readerTextView] setText:displayString];
The above code generates the correct view, but only allows for one size of text for the entire UITextView.
I would like to have the verse number that precedes each verse to be a smaller size font than its verse, but have not found a way to make it work. I've been reading through the documentation, and it seems that this should be possible with TextKit and CoreText through the use of attributed strings, but I can't seem to get this to compile.
I do not want to load the view as a UIWebView.
Any suggestions for this are greatly appreciated.
You're looking for NSAttributedString and NSMutableAttributedString. You should read Introduction to Attributed String Programming Guide. They're generally like normal strings, but additionally contain attributes with ranges to which they apply. One more method that would be helpful to you is:
[self readerTextView].attributedText = yourAttributedString;
If you have some specific problems with attributed strings, please post your code.

Resources