Attributed text disappears in UITextView- Objective C - objective-c

I have an array which has index 0 already filled, and this array stores NSStrings. I also have a "parallel" array which has index 0 already filled, and it stores NSNumbers.
In implementation:
#implementation ViewController
NSMutableArray *intonationStrings;
NSMutableArray *intonationSizes;
In viewDidLoad():
- (void)viewDidLoad {
[super viewDidLoad];
intonationStrings = [[NSMutableArray alloc] initWithObjects:#"placeholderxyz", nil];
NSNumber *placeholderXYZ = [NSNumber numberWithInt:0];
intonationStrings = [[NSMutableArray alloc] initWithObjects:placeholderXYZ, nil];
_resizeLyrics.minimumValue = 9;
_resizeLyrics.maximumValue = 40;
There is a slider with a minimum value of 9 and maximum of 40 which represents font size. There is a text field, and it's current text is used to create an NSRange within a text view to begin attributing the text. This action takes place inside of a button action:
-(IBAction)applyResizeAct:(id)sender{
NSString *lyricString = _lyricPad.text;
NSString *searchString = _searchLyrics.text;
NSMutableAttributedString *lyricStringMut = [[NSMutableAttributedString alloc] initWithString: lyricString];
float sliderValue = _resizeLyrics.value;
[intonationStrings addObject:searchString];
[intonationSizes addObject:[NSNumber numberWithInt:sliderValue]];
for (int i=1; i<[intonationStrings count]; i++){
NSRange searchStringRange = [lyricString rangeOfString:intonationStrings[i]];
NSInteger searchStringNewSize = [intonationSizes[i] integerValue];
int searchStringNewSizeInteger = (int) searchStringNewSize;
[lyricStringMut addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Menlo" size:searchStringNewSizeInteger]
range:searchStringRange];
}
self.lyricPad.attributedText = lyricStringMut;
}
The issue is I can't seem to figure out why typing "Pasta" in the text field, setting the slider to about 25 and tapping the button simply makes the word "Pasta" in the text view holding "Pasta is good." just disappear. My attribute should be applied: Font type Menlo at size 25 for "Pasta" and other sizes applied to strings in the parallel mutable array. Anything helps. Thanks in advance!

Related

All objects in array (interpreted from csv) being returned as the same object (the last object)

What I am trying to achieve, is to convert a csv file into an array of custom objects, however, my attempts at this seem to result in all of the objects in the array being returned as the same object (the last object in the array).
Before I explain further, here is the code:
- (NSArray *)arrayFromCSVFileName:(NSString *)csvFileName fileType:(NSString *)fileType {
// Convert the file into an NSData object
NSString *studentFilePath = [[NSBundle mainBundle] pathForResource:csvFileName ofType:fileType];
NSData *studentData = [NSData dataWithContentsOfFile:studentFilePath];
// Convert the NSData into an NSString
NSString *csvString = [[NSString alloc] initWithData:studentData encoding:NSUTF8StringEncoding];
// Split each record (line) in the csvDataString into an individual array element (split on the newline character \n)
NSArray *csvArray = [csvString componentsSeparatedByString:#"\n"];
// Create an array to hold the parsed CSV data
NSMutableArray *parsedCSVArray = [[NSMutableArray alloc] init];
NSMutableArray *elementArray = [[NSMutableArray alloc] init];
CGSElement *elementToAdd = [[CGSElement alloc] init];
// Loop through each line of the file
for (int i = 0; i < [csvArray count]; i++) {
// Get a reference to this record (line) as a string, and remove any extranous new lines or alike
NSString *csvRecordString = [[csvArray objectAtIndex:i] stringByReplacingOccurrencesOfString:#"\r" withString:#""];
// Split the line by the comma delimeter
NSArray *csvRecordArray = [csvRecordString componentsSeparatedByString:#","];
// Check that there are actually fields (i.e. this is not a blank line)
if ( ([csvRecordArray count] > 0) && ([[csvRecordArray objectAtIndex:0] length] > 0) ) {
elementToAdd.mass = [[csvRecordArray objectAtIndex:1] floatValue];
elementToAdd.atomicNumber = [[csvRecordArray objectAtIndex:0] intValue];
elementToAdd.name = [csvRecordArray objectAtIndex:2];
elementToAdd.symbol = [csvRecordArray objectAtIndex:3];
elementToAdd.period = [[csvRecordArray objectAtIndex:4] intValue];
[elementArray addObject:elementToAdd];
}
}
for (int i = 0; i < [elementArray count]; i++) {
NSLog(#"%i", i);
CGSElement *current = [elementArray objectAtIndex:i];
NSLog(#"Name = %#", current.name);
}
// Return the parsed array
return elementArray;
}
The custom object in question is the CGSElement object, which I am attempting to fill the elementArray with. However, my debug code (the following section of code):
for (int i = 0; i < [elementArray count]; i++) {
NSLog(#"%i", i);
CGSElement *current = [elementArray objectAtIndex:i];
NSLog(#"Name = %#", current.name);
}
Is resulting, rather than in the return of all of the correct element names, it is returning the last element (to put this in context, ununoctium), 118 times.
After some testing, I can safely say that up until after this point:
elementToAdd.mass = [[csvRecordArray objectAtIndex:1] floatValue];
elementToAdd.atomicNumber = [[csvRecordArray objectAtIndex:0] intValue];
elementToAdd.name = [csvRecordArray objectAtIndex:2];
elementToAdd.symbol = [csvRecordArray objectAtIndex:3];
elementToAdd.period = [[csvRecordArray objectAtIndex:4] intValue];
All of the elements are being correctly defined, rather than just the same element over and over.
Needless to say, I'm stumped as to why it would be returning the same object over and over. Any help would be appreciated.
This line:
CGSElement *elementToAdd = [[CGSElement alloc] init];
Should be inside your loop, just before you try to edit the object and add it to the array. Currently you are repeatedly mutating the same object instead of creating new objects for each record.
You add the same entity all the time. It is crated once before the loop and within the loop it values are changed again and angan and it is added to the array. Naturally all items in the aray carry the same values because it is the same object.
If you want then change the array with an NSSet. To a set an object can only added once and you will end up with a set of 1. That is not the solution of couse, it would just visualize what is happening.
To solve it move this line
CGSElement *elementToAdd = [[CGSElement alloc] init];
to the beginning of the body of the for i loop, so that a new instance is created for every iteration and therefore for every index of the array.

getting text from uilabel in objective-c

I have a project where I am trying to grab text from a uilabel that has been populated from a web service. I can grab and manipulate the text just fine but I need to send certain characters from the string to another web service call. I can not figure out how to grab the first, second and last characters in my string. I am both new to Objective-C as well as programming so any help would be much appreciated.
You can do it like this:
UILabel * l = [[UILabel alloc] init];
l.text = #"abcdef"; //set text to uilabel
[self.view addSubview:l];
NSString * text = l.text; //get text from uilabel
unichar first = [text characterAtIndex:0]; //get first char
unichar second = [text characterAtIndex:1];
unichar last = [text characterAtIndex:text.length -1];
If you need results as strings you can use:
NSString * firstAsString = [text substringWithRange:NSMakeRange(0, 1)]; //first character as string
or you can convert the unichar to string like this:
NSString * x = [NSString stringWithFormat:#"%C", last];
Per this it should be fairly easy:
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UILabel_Class/Reference/UILabel.html
textLabel.text = #"Foo";
Where textLabel is instance of UILabel

NSMutableDictionary containing UIImageViews...Add mutable copy to an NSMutableArray? Alternative?

I'm trying to build words in arrays by their key value in a dictionary. However, it won't work the way I'd like it to, because I can't "copy" a UIImageView.
It would be PERFECT, if when adding the letter from the dictionary to an array, it gives me a copy instead of the real object. I don't want to make multiple images of the same letter and add it to the dictionary, because then I could no longer call it by key "s" or "a", and I need more than one array to use the same letters at at time.
What can I do?
//How I create the letters
char s = 's';
NSString *key = [NSString stringWithFormat:#"%c", s];
alphabetS = [[UIImageView alloc] init]];
[alphabetS setImage:[UIImage imageNamed:#"s.png"]];
[allTilesDictionary setObject:alphabetS forKey:key];
[alphabetS release];
//How I use the imageviews from the dictionary
NSMutableArray *wordOne = [[NSMutableArray alloc] initWithObjects:[allTilesDictionary objectForKey:#"s"],[allTilesDictionary objectForKey:#"h"],[allTilesDictionary objectForKey:#"o"],[allTilesDictionary objectForKey:#"p"], nil];
EDIT: My solution. It works perfectly.
for (UIImageView *letters in wordOne)
{
newLetter = [[UIImageView alloc] init];
newLetter.image = letters.image;
newLetter.userInteractionEnabled = YES;
//I can now either lay them out wherever I want on the view, or add them to a new array.
}
Your original code, slightly modified:
//How I create the letters
char s = 's';
NSString *key = [NSString stringWithFormat:#"%c", s];
[allTilesDictionary setObject:[UIImage imageNamed:#"s.png"] forKey:key];
//How I use the imageviews from the dictionary
NSMutableArray *wordOne = [[NSMutableArray alloc] initWithObjects:[allTilesDictionary objectForKey:#"s"],[allTilesDictionary objectForKey:#"h"],[allTilesDictionary objectForKey:#"o"],[allTilesDictionary objectForKey:#"p"], nil];
Your use of that code, slightly modified:
for (UIImage *letters in wordOne)
{
newLetter = [[UIImageView alloc] init];
newLetter.image = letters;
newLetter.userInteractionEnabled = YES;
//I can now either lay them out wherever I want on the view, or add them to a new array.
}
No unnecessary UIImageViews created.
for (UIImageView *letters in wordOne)
{
newLetter = [[UIImageView alloc] init];
newLetter.image = letters.image;
newLetter.userInteractionEnabled = YES;
//I can now either lay them out wherever I want on the view, or add them to a new array.
}

Dynamically Create Object Within Loop - Objective C

I'm looking for a way to dynamically create NSString objects in objective C based on how many of them I need (between 1 and 5). I then want to use those strings as names of objects which also are dynamically created;
Pseudo Code:
for (i=1, i <= number_of_characters, i++)
{
NSMutableString* theString = [NSMutableString character];
[theString appendString:[NSString stringWithFormat:#"%i ",i]];
UILabel *theString;
[theString release];
}
and I am hoping to get several UILabel objects named:
character1
character2
character3
and so on...
Thanks!
You can create UILabel objects on the fly, but you can't create variables at runtime. If you want to set the text of the label to theString, that's no problem:
NSMutableArray *labels = [NSMutableArray array];
for (i=1, i <= number_of_characters, i++)
{
NSMutableString* theString = [NSString stringWithFormat:#"%i ",i];
UILabel *label = [[UILabel alloc] initWithFrame:someCGRect];
label.text = theString;
[labels addObject:label];
[theString release];
}
Now you've got an array full of labels, each of which has a number as its text. The labels haven't been added to any view yet, so you'll want to take care of that.

How can I convert the characters in an NSString object to UILabel objects?

I'm trying to figure out how to take the individual characters in an NSString object and create UILabels from them, with the UILabel text set to the individual character.
I'm new to Cocoa, but so far I have this...
NSString *myString = #"This is a string object";
for(int i = 0; i < [myString length]; i++)
{
//Store the character
UniChar chr = [myString characterAtIndex:i];
//Stuck here, I need to convert character back to an NSString object so I can...
//Create the UILabel
UILabel *lbl = [[UILabel alloc] initWithFrame....];
[lbl setText:strCharacter];
//Add the label to the view
[[self view] addSubView:lbl];
}
Aside from where I'm stuck, my approach already feels very hackish, but I'm a noob and still learning. Any suggestions for how to approach this would be very helpful.
Thanks so much for all your help!
You want to use -substringWithRange: with a substring of length 1.
NSString *myString = #"This is a string object";
NSView *const parentView = [self superview];
const NSUInteger len = [myString length];
for (NSRange r = NSMakeRange(0, 1); r.location < len; r.location += 1) {
NSString *charString = [myString substringWithRange:r];
/* Create a UILabel. */
UILabel *label = [[UILabel alloc] initWithFrame....];
[lbl setText:charString];
/* Transfer ownership to |parentView|. */
[parentView addSubView:label];
[label release];
}