I know that I can do this:
switch (imageNumber) {
case 1: image1.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"jpg"]]; break;
case 2: image2.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"jpg"]]; break;
case 3: image3.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"jpg"]]; break;
case 4: image4.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"jpg"]]; break;
}
I want to be more efficient in my code, so I am wondering if there is a way to do it like this:
switch (imageNumber) {
case 1: //somehow set image1 as the imageView I want used
case 2: //somehow set image2 as the imageView I want used
case 3: //somehow set image3 as the imageView I want used
case 4: //somehow set image4 as the imageView I want used
}
imageWhicheverWasSet.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"jpg"]];
Thanks in advance for your help!
The second code snippet you pasted yourself is actually very close to a solution. You just need to set UIImageView *imageToChange; as instance variable and then do:
imageToChange.image = nil; // will clear the image on last selected image view
// if you don't need that, just remove that line and leave others
switch (imageNumber) {
case 1: imageToChange = image1; break;
case 2: imageToChange = image2; break;
case 3: imageToChange = image3; break;
case 4: imageToChange = image4; break;
}
imageToChange.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"jpg"]];
You could put the UIImageViews in an array, then use the index to select the correct one. Not sure this would be useful unless you had a lot more UIImageViews to deal with.
NSArray* imageViews = [NSArray arrayWithObjects: image1, image2, image3, image4, nil];
UIImageView* theImage = [imageViews objectAtIndex: imageNumber-1];
UIImage* theImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"jpg"]];
You'd want to validate the imageNumber to make sure it was within range.
How about --
UIImage* theImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"jpg"]];
switch ...
case 1:image1.image = theImage; break;
case 2:...
You could also do --
MyImageType* tempImageObj = nil;
switch ... {
case 1:tempImageObj = &image1; break; // Or just image1, if ".image" is a property, not a field
case 2:...
}
tempImageObj ->image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"imageName" ofType:#"jpg"]]; // Or "." instead of "->" if property.
Another way could be to use an array
UIImageView *iv[] = {
image1,
image2,
image3,
image4,
};
if (imageNumber>=0 && imageNumber<4)
iv[imageNumber].image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:#"imageName"
ofType:#"jpg"]]
Related
I want to put defaults images if i don't have images from url feed.
if(![[stories objectAtIndex:storyIndex] valueForKey:#"url"]==nil)
{ NSNumber *numberOfKeyInstances = [stories valueForKey:#"key"];
imageArray=[NSArray arrayWithObjects:[UIImage imageNamed:#"1.png"],nil];
int randomNumber_ = rand ()%19;
UIImage *image = [imageArray objectAtIndex:indexPath.row];
cell.imag=image;
}
else{
if (![[[stories objectAtIndex:storyIndex] valueForKey:#"url"] isEqualToString:#""]) {
[cell.imag setImageWithURL:[NSURL URLWithString:[[stories objectAtIndex:storyIndex] objectForKey:#"url"]] placeholderImage:[UIImage imageNamed:#"Alb.png"]];
}
}
This is my code, but i get [UIImage setContentMode:]: unrecognized selector sent to instance 0x7f908c1dcce0'
How can i solved?
Firstly, imageArray is initialised with only one image. So calling [imageArray objectAtIndex:indexPath.row] is a problem. You dont need an image array for that. Secondly, the argument inside the first if statement doesn't look right.
Also, as #midhun-mp Pointed out, u should be probably using cell.imag.image.
Try this :
if([[stories objectAtIndex:storyIndex] valueForKey:#"url"] == nil)
{
cell.imag.image = [UIImage imageNamed:#"1.png"];
}
else if ([[[stories objectAtIndex:storyIndex] valueForKey:#"url"] isEqualToString:#""])
{
cell.imag.image = [UIImage imageNamed:#"1.png"];
}
else
{
//SET YOUR IMAGE HERE
}
Try to change
UIImage *image = [imageArray objectAtIndex:indexPath.row];
to
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:[imageArray objectAtIndex:indexPath.row]]];
I suspect that cell.imag is a UIImageView not UIImage property.
So you need to change:
cell.imag=image;
to
cell.imag.image = image;
I have a random method to create 2 random integers. My concern is that %65-%70 of outputs are same integers like "5-5" "4-4" "3-3".
-(void)random{
NSUInteger randomNumber = arc4random_uniform(5);
switch (randomNumber) {
case 0:
_tile2.image = [UIImage imageNamed:#"one.png"];
break;
case 1:
_tile2.image = [UIImage imageNamed:#"two.png"];
break;
case 2:
_tile2.image = [UIImage imageNamed:#"three.png"];
break;
case 3:
_tile2.image = [UIImage imageNamed:#"four.png"];
break;
case 4:
_tile2.image = [UIImage imageNamed:#"five.png"];
break;
}
NSUInteger randomNumber2 = arc4random_uniform(5);
switch (randomNumber2) {
case 0:
_tile3.image = [UIImage imageNamed:#"one.png"];
break;
case 1:
_tile3.image = [UIImage imageNamed:#"two.png"];
break;
case 2:
_tile3.image = [UIImage imageNamed:#"three.png"];
break;
case 3:
_tile3.image = [UIImage imageNamed:#"four.png"];
break;
case 4:
_tile3.image = [UIImage imageNamed:#"five.png"];
break;
}
}
Should i create 25 different case to reach better result?
NSUInteger randomNumber = arc4random_uniform(25);
switch (randomNumber) {
case 0:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"one.png"];
break;
case 1:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"two.png"];
break;
case 2:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"three.png"];
break;
case 3:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"four.png"];
break;
case 4:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"five.png"];
break;
case 5:
_tile2.image = [UIImage imageNamed:#"two.png"];
_tile3.image = [UIImage imageNamed:#"one.png"];
break;
...
}
}
arc4random_uniform is great for getting one random integer. When i need to get 2 or more random numbers, the outputs are not that great. What is the best way of doing this?
Sorry, but I don't believe you. You must be doing something other than what you've shown. The following code pasted into Playground consistently gives around a 20% match, not the 65-70% you claim:
import Cocoa
let sampleSize = 1000
var count = 0
for i in 1...sampleSize {
var randomNumber1 = arc4random_uniform(5)
var randomNumber2 = arc4random_uniform(5)
if randomNumber1 == randomNumber2 {
++count
}
}
println( Double(count) / Double(sampleSize) )
Whatever problem you're having, it isn't with how arc4random_uniform generates pairs of values.
Would using an array of numbers be a solution for you?
You can have a mutable array of numbers `[#0, #1, #2, #3, #4] and retrieve one number from a random index
NSMutableArray *array = [NSMutableArray arrayWithObjects:#0, #1, #2, #3, #4];
NSInteger firstIndex = arc4random_uniform([array count]);
NSNumber *firstNumber = array[index];
Remove the number you've just found:
[array removeObjectAtIndex:firstIndex];
And than repeat the same for the second number. The first retrieved number won't be in the array anymore so even if the arc4random_uniform() gives you the same value (your 65-70% case) the actual number you are gonna use in your switch case it's gonna be different.
This approach is probably a bit clumsy, but I think it does what you need giving you a bit of control over the randomness.
I use the following code to create borders around images. I loop through the following multiple times to create thumbnail images with borders that are then placed in a UICollectionView.
The problem seems to be that every time I reload the UICollectionView the images are not being released from memory and it seems to build up to the point where it crashes. I don't think it is the UICollectionView code because If I run it with images that don't require a border I don't get any issues.
- (UIImage *)applyFrame:(UIImage *)image selectedFrame:(NSString *)selectedFrame {
UIImage *frame;
NSLog(#"Image Size For Frames: %f, %f",image.size.width,image.size.height);
if(image.size.width == image.size.height){
frame = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#-Square.png",selectedFrame] ofType:nil]];
}
if(image.size.width > image.size.height){
frame = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#.png",selectedFrame] ofType:nil]];
}
if(image.size.width < image.size.height){
frame = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#.png",selectedFrame] ofType:nil]];
frame = [self rotateUIImage:frame clockwise:true];
}
GPUImageAlphaBlendFilter *blendFilter = [[GPUImageAlphaBlendFilter alloc] init];
GPUImagePicture *imageToProcess = [[GPUImagePicture alloc] initWithImage:image];
GPUImagePicture *border = [[GPUImagePicture alloc] initWithImage:frame];
blendFilter.mix = 1.0f;
[imageToProcess addTarget:blendFilter];
[border processImage];
[border addTarget:blendFilter];
[imageToProcess processImage];
return [blendFilter imageFromCurrentlyProcessedOutput];
}
- (UIImage*)rotateUIImage:(UIImage*)sourceImage clockwise:(BOOL)clockwise {
CGSize size = sourceImage.size;
UIGraphicsBeginImageContext(CGSizeMake(size.height, size.width));
[[UIImage imageWithCGImage:[sourceImage CGImage] scale:1.0 orientation:clockwise ? UIImageOrientationRight : UIImageOrientationLeft] drawInRect:CGRectMake(0,0,size.height ,size.width)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
UIImage imageWithContentsOfFile: returns an autorelease object, which will be released only when the app returns to the current run loop. So, might it be that you app loops for a long time executing this code? In this case, the autorelease objects might accumulate, and increase the heap usage.
If so, you could try to insert into the body of the responsible loop an autorelease block:
#autoreleasepool {
...your statements
}
My code for my images is
-(IBAction)start:(id)sender
{
animation.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"Paddle 1.png"],
[UIImage imageNamed:#"Paddle 2.png"],
[UIImage imageNamed:#"Paddle 3.png"],
[UIImage imageNamed:#"Paddle 4.png"],
nil];
[animation setAnimationRepeatCount:0];
animation.animationDuration = 2.5;
[animation startAnimating];
}
This is caching too much memory and I was told in a previous question to swap my code to using
[UIImage imageWithContentsOfFile: GetImgWithoutCaching(#"Paddle 1.jpg")]
and
UIImage* GetImgWithoutCaching(NSString* imgName)
{
NSString *imagePath = [[NSBundle mainBundle] pathForResource:imgName ofType:nil];
return [UIImage imageWithContentsOfFile:imagePath];
}
What is the correct way of writing the code? do i place that code in my .m as is?
First you should check if using retina picture:
BOOL isHighResolution = NO;
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
if ([UIScreen mainScreen].scale > 1) {
isHighResolution = YES;
}
}
if you are using retina picture, add #2x to image name, like this:
NSString *noExtFileName = [name stringByDeletingPathExtension];
if (isHighResolution) {
if (![noExtFileName hasSuffix:#"#2x"]) {
noExtFileName = [noExtFileName stringByAppendingString:#"#2x"];
}
}
//if image only "png" type
return [[NSBundle mainBundle] pathForResource:noExtFileName ofType:#"png"];
Since your GetImgWithoutCaching function returns a UIImage you would need:
-(IBAction)start:(id)sender
{
animation.animationImages = [NSArray arrayWithObjects:
GetImgWithoutCaching(#"Paddle 1.jpg"),
GetImgWithoutCaching(#"Paddle 2.jpg"),
GetImgWithoutCaching(#"Paddle 3.jpg"),
GetImgWithoutCaching(#"Paddle 4.jpg"),
nil];
[animation setAnimationRepeatCount:0];
animation.animationDuration = 2.5;
[animation startAnimating];
}
I have been trying to animate using an NSTimer and I've set up my code like this:
- (IBAction)startClick:(id)sender{
animationTimer = [NSTimer scheduledTimerWithTimeInterval:(.1/25.0) target:self selector:#selector(tick) userInfo:nil repeats:YES];
}
- (void)tick{
[self animatePig];
}
- (void)animatePig{
UIImage *pigImage1 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0004.png" ofType:nil] ];
UIImage *pigImage2 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0005.png" ofType:nil] ];
UIImage *pigImage3 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0006.png" ofType:nil] ];
UIImage *pigImage4 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0007.png" ofType:nil] ];
UIImage *pigImage5 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0008.png" ofType:nil] ];
UIImage *pigImage6 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0009.png" ofType:nil] ];
UIImage *pigImage7 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0010.png" ofType:nil] ];
UIImage *pigImage8 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0011.png" ofType:nil] ];
UIImage *pigImage9 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0012.png" ofType:nil] ];
UIImage *pigImage10 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0013.png" ofType:nil] ];
UIImage *pigImage11 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0014.png" ofType:nil] ];
UIImage *pigImage12 =[UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"gordonapple0015.png" ofType:nil] ];
if(gordon.image == pigImage1)
gordon.image = pigImage2;
else if(gordon.image == pigImage2)
gordon.image = pigImage3;
else if(gordon.image == pigImage3)
gordon.image = pigImage4;
else if(gordon.image == pigImage4)
gordon.image = pigImage5;
else if(gordon.image == pigImage6)
gordon.image = pigImage7;
else if(gordon.image == pigImage7)
gordon.image = pigImage8;
else if(gordon.image == pigImage8)
gordon.image = pigImage9;
else if(gordon.image == pigImage9)
gordon.image = pigImage10;
else if(gordon.image == pigImage10)
gordon.image = pigImage11;
else if(gordon.image == pigImage11)
gordon.image = pigImage12;
else
gordon.image = pigImage12;
}
Does anyone know why this only animates the first frame? The problem's probably very simple to fix, i'm just too much of a noob in iPhone development to notice.
----------Edit----------
Okay, I have got my NSTimer to work correctly, and my next step was to stop my animation repeating over and over, so I invalidated my timer like this:
[animationTimer invalidate];
And now, when the timer is called again it doesn't work, so how would I validate it again? (re-instantiate it I think)
(BTW I Have set up another SO question for this)
My code as of now:
- (IBAction)startClick:(id)sender{
animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.00/30.00) target:self selector:#selector(tick) userInfo:nil repeats:YES];
}
- (void)tick{
[self animatePig];
}
- (void)animatePig{
UIImage *pigImage1=[UIImage imageNamed:#"gordonapple0004.png"];
UIImage *pigImage2=[UIImage imageNamed:#"gordonapple0005.png"];
UIImage *pigImage3=[UIImage imageNamed:#"gordonapple0006.png"];
UIImage *pigImage4=[UIImage imageNamed:#"gordonapple0007.png"];
UIImage *pigImage5=[UIImage imageNamed:#"gordonapple0008.png"];
UIImage *pigImage6=[UIImage imageNamed:#"gordonapple0009.png"];
UIImage *pigImage7=[UIImage imageNamed:#"gordonapple0010.png"];
UIImage *pigImage8=[UIImage imageNamed:#"gordonapple0011.png"];
UIImage *pigImage9=[UIImage imageNamed:#"gordonapple0012.png"];
UIImage *pigImage10=[UIImage imageNamed:#"gordonapple0013.png"];
UIImage *pigImage11=[UIImage imageNamed:#"gordonapple0014.png"];
UIImage *pigImage12=[UIImage imageNamed:#"gordonapple0015.png"];
UIImage *pigImage13=[UIImage imageNamed:#"gordonapple0016.png"];
if(gordon.image == pigImage1)
gordon.image = pigImage2;
else if(gordon.image == pigImage2)
gordon.image = pigImage3;
else if(gordon.image == pigImage3)
gordon.image = pigImage4;
else if(gordon.image == pigImage4)
gordon.image = pigImage5;
else if(gordon.image == pigImage5)
gordon.image = pigImage6;
else if(gordon.image == pigImage6)
gordon.image = pigImage7;
else if(gordon.image == pigImage7)
gordon.image = pigImage8;
else if(gordon.image == pigImage8)
gordon.image = pigImage9;
else if(gordon.image == pigImage9)
gordon.image = pigImage10;
else if(gordon.image == pigImage10)
gordon.image = pigImage11;
else if(gordon.image == pigImage11)
[animationTimer invalidate];
else
gordon.image = pigImage1;
}
You're going about it the hard way.
Create a UIImageView and put it on the screen.
Load your images into an NSArray.
Set the UIImageView's animationImages property to the array.
You can adjust the animationDuration and animationRepeatCount properties as well.
When user presses the start button, call the startAnimating method of the image view.
You don't need the timer nor the manual frame advancing code.
There's no good way to know without seeing more code from you. How do you store "gordon"? What type is it? presumably some type of UIImageView?
However, your real problem (if I may go to a higher level) is your entire structure. Try something more like this:
// Interface file
NSMutableArray *pigImages;
int pigImageIndex;
// Implementation file
const int firstImageIndex = 4;
const int lastImageIndex = 15;
const int imageCount = (lastImageIndex + 1 - firstImageIndex);
- (void) initPigImages
{
pigImages = [[NSMutableArray alloc] initWithCapacity: imageCount];
for (int i = firstImageIndex; i <= lastImageIndex; ++i)
{
[pigImages addObject: [self makePigImageWithIndex: i]];
}
pigImageIndex = 0;
}
- (UIImage*) makePigImageWithIndex: (int) imageIndex
{
NSString *imageName = [NSString stringWithFormat: #"gordonapple%4d.png", imageIndex]; // Formatting may be a little off.
return [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: imageName ofType: nil]]];
}
- (void )animatePig
{
if (pigImageIndex < imageCount)
{
gordon.image = pigImages[pigImageIndex++];
}
}
To restart your timer you can use -[NSRunLoop addTimer:forMode:] or just release and create a new timer each time.