I'm working with an image heavy iOS app and I found myself typing almost the same line again and again:
...
A016.image = [UIImage imageNamed:img21];
A017.image = [UIImage imageNamed:img21];
A018.image = [UIImage imageNamed:img21];
...
Now I ask you: is there a way where I could store the UIImageViews names in an Array or something?
Only to beautify my very ugly code.
/John
Yes, you can put the UIImageViews in an array and put it in a for.
UIImageView * imageView1;
UIImageView * imageView2;
UIImageView * imageView3;
NSArray * imageViewsArray = [NSArray arrayWithObjects:imageView1,imageView2,imageView3,nil];
for (UIImageView * currentImageView in imageViewsArray) {
currentImageView.image = [UIImage imageNamed:img21];
}
Of course you can simplify something like that. But it's not entirely clear what the context is exactly.
If you have all your image views in an array you could do something like this.
// Assume an NSArray called imageViews exists with all the UIImageView instances in it.
for (UIImageView *imageView in imageViews) {
imageView.image = [UIImage imageNamed:img21];
}
If your image views aren't in an array already and are actually called A016, A017 etc., then I'd recommend you change your code design. Something like this is never a good idea. It results in bad, difficult to maintain code. If this is some kind of table of images, try putting the image views in an array in the first place.
That being said, there are ways to put variables like that in an array. If they are declared as #properties or ivars you can could do something like this.
NSMutableArray *imageViews = [NSMutableArray arrayWithCapacity:20];
for (int i = 0; i < 20; i++) {
NSString *variableName = [NSString stringWithFormat:#"A0%d", i];
UIImageView *imageView = [self valueForKey:variableName];
[imageViews addObject:imageView];
}
After that you can save the array as an ivar and do the same thing as above.
A more hardcoded version would be to simply put the image views into an array yourself:
NSArray *imageViews = [NSArray arrayWithObjects:..., A016, A017, A018,..., nil];
But I really recommend not using indexed variable names like that.
Related
I like to combine multiple lines of code into one, when I can. Example:
int64_t siz = [self getFileSizeAsInt64_t: filePath];
NSString * str = [self convLongLongToCommaStr: siz];
return( str );
becomes
return [self convLongLongToCommaStr: [self getFileSizeAsInt64_t: filePath]];
Here is an example of a three-line code pattern I see in my code a lot that I'd like to combine into one line. But, I've not been able to do it and I'm not sure if it is even possible.
UIImageView * imgView = ctlObjs[iImgIdx];
[imgView setImage: nextImage];
ctlObjs[iImgIdx] = imgView;
Thanks for any insights on how to do this, if it is possible.
As Yar points out, that third line is not necessary. But you could combine the first two like so:
[ctlObjs[iImgIdx] setImage:nextImage];
Or, if ctlObjs is a NSArray or NSMutableArray, you might want the following, which makes the intent clear and offers better code completion:
[(UIImageView *) ctlObjs[iImgIdx] setImage:nextImage];
Having said that, the fact that you can combine multiple lines of code into one doesn't mean that you necessarily should. IMHO, code legibility is probably more important than compactness. I personally would stick with:
UIImageView *imgView = ctlObjs[iImgIdx];
[imgView setImage: nextImage];
Just
[ctlObjs[iImgIdx] setImage:nextImage];
I have to create a number of UIImageViews based on values stored in an NSString. The value that is stored will become the name for my UIImageView, each one will be created individually of course.
So to keep things simple my question is, can one create a UIImageView based on the value stored within an NSString?
Rough Example:
-(UIImageView)createMyFruitViews:(NSString *)fruit
{
NSString *fruit = #"";
UIImageView *fruitImage [fruit value]; //<-- made up for example purposes.
return fruitImage;
}
If this is not possible, could you please suggest a way around this?
FYI I've read through the forums too, the only thing that comes close is How to use NSSstring to instantiate a UIImageview; however I don't understand the answer and I am not sure that it can apply to what I need.
Try using UIImageView *fruitImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:fruit]];
I'm not quite sure I understood what you need... as far as I can tell, you have the name of an image on a NSString object, right?
Lets say you have an array of strings, each string representing the name of an image:
NSArray *myImageNames = [NSArray arrayWithObjects:#"image1.png", #"image2.png", #"image3.png", nil];
Then you'll create your imageViews using these images:
for (NSString *imageName in myImageNames) {
UIImageView *myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
[self.view addSubview:myImageView];
[myImageView release]; // If you're not using ARC
}
If I didn't get exactly what you need, please let me know.
I am trying to create a model with multiple images in a factory model style. I have one class that handles the individuals, one class that handles the group of individuals and a ViewController.
testImage = [[UIImageView alloc] initWithFrame:CGRectMake(250, 500, 30, 30)];
testImage.image = [UIImage imageNamed:#"myImage.png"];
testImage.animationDuration = 1.5;
testImage.contentMode = UIViewContentModeCenter;
[self.view addSubview:testImage];
http://jcdeveloperworld.blogspot.com/2009/07/iphone-game-tutorial-part-1.html -- Thanks
That code works when it is just in the viewController, and now I am trying to make the individuals keep track of their own image. So i put the
testImage = [[UIImageView alloc] initWithFrame:CGRectMake(250, 500, 30, 30)];
testImage.image = [UIImage imageNamed:#"myImage.png"];
testImage.animationDuration = 1.5;
testImage.contentMode = UIViewContentModeCenter;
[self.view addSubview:testImage];
in a separate class and then tried to display it from my viewController. It is my understanding that I can't just tell the viewController to display something from a separate class.
flock *newFlock = [[flock alloc] init];
[newFlock makeFlock];
NSMutableArray *tempFlock = [[NSMutableArray alloc] init];
tempFlock = newFlock.theFlock;
individualsClass *tempIndividual = [[individualsClass alloc] init];
tempIndividual = [tempFlock objectAtIndex:0];
UIImageView *tempImage = [[UIImageView alloc] initWithFrame:CGRectMake(250, 500, 30, 30)];
tempImage = tempIndividual.individualImage;
[self.view addSubview:tempImage];
I also tried it without all the copying, but the dot notation started to get in the way because I'm accessing properties of objects in an NSMutableArray (which seems absurdly difficult in objective C). I could use some help in figuring that out too
ie.
flock.[theFlock.individualImage.image objectAtIndex:1] //Doesn't work
I am kind of new to objective C, so perhaps I'm attacking this problem wrong. This is being done for an iPad app
It's not clear what you're trying to do, but you're definitely doing a lot of stuff you don't need to. Consider these lines of your code:
NSMutableArray *tempFlock = [[NSMutableArray alloc] init];
tempFlock = newFlock.theFlock;
The first line declares a variable named tempFlock of type NSMutableArray *. Then it creates and initializes an empty NSMutableArray and assigns it to tempFlock. The second line then assigns newFlock.theFlock to tempFlock, overwriting the only reference to the array you created in the first line. You can just say this:
NSMutableArray *tempFlock = newFlock.theFlock;
Anyway, the correct syntax for your last block is this:
[flock.theFlock objectAtIndex:1].individualImage.image
So maybe this is what you want to do:
[self.view addSubview:[flock.theFlock objectAtIndex:1].individualImage];
Also, flock and individualsClass are not good class names in Objective-C. Flock and Individual might be better names.
And it's confusing that flock instances have a property named theFlock. It looks like theFlock is just an array of individuals, so a better name for the property would probably be individuals.
If all the "dot" syntax is causing problems with understanding just don't use them, they are just an alternate syntax for method invocation.
[myInstance value] is the same as myInstance.value, which can be viewed as a simple substitution.
Also avoiding long compound statements can help understanding, instead use one or more intermediate well named variables. Trust the compiler to optimize them.
So, as #rob writes:
[flock.theFlock objectAtIndex:1].individualImage.image
the equivalent could be:
[[[[flock theFlock] objectAtIndex:1] individualImage] image]
Broken into multiple statements:
tempFlock = [[flock theFlock] objectAtIndex:1];
tempIndividual = [tempFlock individualImage];
image = [tempIndividual image];
Brand new to coding; been utilizing stackoverflow religiously for months; first time asking a question; please be gentle.
I'm trying to create a series of UITextFields programmatically using a for loop. The fields should have names like "pax1name", "pax2name", "pax3name", etc.
The piece I'm missing is how to take a string and make it the name of a textField, changing the name of the textField each time the for-loop executes.
Here's my code, but maybe I'm going about this the wrong way? Thank you in advance!
// set up the names textfields
for (int i = 0; i < 7; i++) {
NSString *fieldName = [[NSString alloc] initWithFormat:#"pax%iname", (i + 1)];
// I can't figure out what goes here to create a UITextField with the name of fieldName
textField = [[UITextField alloc] initWithFrame:CGRectMake(15, (15 + (i * 40)), 400, 40)];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.font = [UIFont systemFontOfSize:15.0];
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
[namesViewController addSubview: textField];
[fieldName release];
[textField release];
}
Normally you use the UIView property tag for that. Use [textField setTag:<youCustomTag>] in your loop to set the value, e.g. your variable i. Please note that tag expect an NSUInteger and not an NSString.
To access the correct text field afterwards you'd call [[namesViewController view] viewWithTag:<yourCustomTag>].
BUT, is it really necessary to create multiple text fields for your view controller? There might be a more elegant solution by creating just one single text field and setting the tag-property on demand when the user taps a row. I don't know if that would work for you.
I think you've been going the wrong way about this. UITextField has no property called "name". To identify a control, you can use its tag property. See this code:
for (int i = 0; i < 7; i++) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(...)];
textField.tag = i + 1;
...
}
When you say the name of the textfield I'm presuming you mean the variable name rather than setting the text that is displayed. I.e. you want to create the variables in a loop, but later be able to reference them individually by name.
In that case, you can't do what you want to do. What you can do is stick them in an array for handy access later on.
NSMutableArray *paxNameFields = [[NSMutableArray alloc] init]; // before your loop
[paxNameFields addObject: textField]; // inside the loop
[paxNameFields objectAtIndex: 5]; //sometime later use the 6th field
Or if you just want to be able to identify which UITextField you're passed into a delegate callback later on, you can set/check the tag property.
UITextFields don't HAVE names. You're probably coming from HTML-world, where these things are basically a big hash of name-value pairs. Not like that in Cocoa Touch. As #Florian Mielke says, they each have an int .tag property, which is probably what you want to set.
I am making a simple game that requires that I draw multiple UIImages in many different places. My problem here is that I need to add the UIImages to an NSMutableArray, and access them later. Using NSStrings to represent the images (such as for paths) will not work here, so I need to know how to change the images for every UIImage in the array.
My code is as follows (at least, for accessing the NSMutableArray). The NSMutableArray is declared in my .h file, and is initialized in a different method.
for (int a = 0; a <= [theArray count]; a ++) {
// I make a UIImage, which I will draw later
UIImage *theImage = [theArray objectAtIndex:a];
// then I do the drawing
}
This works fine. My problem is that I cannot figure out how to change a particular object in the NSMutableArray. How can I do this?
By the way, I am adding the UIImages to the NSMutableArray with the following code.
+ (void) createCarWithImage:(NSString*)theImageName {
UIImage *anImage= [UIImage imageNamed:theImageName];
[theArray addObject:anImage];
}
I think you want to use this method:
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject
e.g.:
[theArray replaceObjectAtIndex:4 withObject:someOtherImage];
Just modify each UIImage in the NSMutableArray as is, you only have a pointer to the actual data. That is, regardless of what pointer you use to change the data, the data is changed for every pointer.
Additionally, you can also iterate over your UIImages with:
for (UIImage *img in theArray)
{
//send messages to img
}
Answer to Comment
You can modify the UIImage at index 4 by:
UIImage *image = [theArray objectAtIndex:4];
//send messages to image