PDA

View Full Version : UIButton to change pathForResource




nickculbertson
Jan 10, 2011, 01:21 PM
Hello,
I am working on an app with two UIButtons and one UIImageView. When button 1 is pressed I would like touches on the UIImageView to play "sound1". When button 2 is pressed I want touches on the same UIImageView to play "sound2".


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location1 = [touch locationInView:touch.view];

if(CGRectContainsPoint(image1.frame, location1))
{ [image1 setHighlighted:YES];
NSString *path = [[NSBundle mainBundle] pathForResource:@"sound1" ofType:@"wav"];
myMusic=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[myMusic play];

}else {
[image1 setHighlighted:NO];
}

Is there a way to change the pathForResouces when button 1 and button 2 are selected to "sound1" and "sound2"?

Thanks,
Nick



dejo
Jan 10, 2011, 01:54 PM
Is there a way to change the pathForResouces when button 1 and button 2 are selected to "sound1" and "sound2"?
Yes. pathForResource: is a parameter that takes an NSString as input. So, rather than passing in a hard-coded string, pass a reference to one whose value is determined by which button was pressed instead.

nickculbertson
Jan 10, 2011, 03:41 PM
Yes. pathForResource: is a parameter that takes an NSString as input. So, rather than passing in a hard-coded string, pass a reference to one whose value is determined by which button was pressed instead.


So, is this getting close?

.h


NSString *myString;



.m

-(IBAction)button1press {
NSString *myString=[[NSString alloc] initWithString:@"sound1"];
}
-(IBAction)button2press {
NSString *myString=[[NSString alloc] initWithString:@"sound2"];
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location1 = [touch locationInView:touch.view];

if(CGRectContainsPoint(image1.frame, location1))
{ [image1 setHighlighted:YES];
NSString *path = [[NSBundle mainBundle] pathForResource:(NSString *)myString ofType:@"wav"];
myMusic=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[myMusic play];

}else {
[image1 setHighlighted:NO];
}


Thanks,
Nick

dejo
Jan 10, 2011, 03:53 PM
So, is this getting close?
Yes, but still some work to do:

1) Your button press methods are assigning to a local variable and not the ivar you've defined in your .h

2) Why are you casting myString when you pass it to pathForResource:?

nickculbertson
Jan 10, 2011, 04:12 PM
Yes, but still some work to do:

1) Your button press methods are assigning to a local variable and not the ivar you've defined in your .h

1) I left this part out before. my bad

#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>


@interface FirstView : UIViewController <AVAudioPlayerDelegate> {

AVAudioPlayer *myMusic;
CGPoint *location1;
UITouch *touch;
IBOutlet UIImageView *image1;
NSString *myString;
IBOutlet UIButton *button1;
IBOutlet UIButton *button2;
}
- (IBAction) button1press;
- (IBAction) button2press;


@property (nonatomic, retain) IBOutlet UIImageView *image1;
@property (nonatomic, retain) IBOutlet UIButton *button1;
@property (nonatomic, retain) IBOutlet UIButton *button2;

@property(nonatomic, retain) AVAudioPlayer* myMusic;


@end


or did you mean that I should have put this...

NSString *myString=[[NSString alloc] initWithString:@"sound1"];

in this method...

if(CGRectContainsPoint(image1.frame, location1))
{ [image1 setHighlighted:YES];
NSString *path = [[NSBundle mainBundle] pathForResource:@"sound1" ofType:@"wav"];
myMusic=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[myMusic play];

}else {
[image1 setHighlighted:NO];
}

2) Why are you casting myString when you pass it to pathForResource:?

2) Monkey see, Monkey do. I found some code on the internet where someone did it like that. Clearly not the right approach. :)

Thanks,
Nick

dejo
Jan 10, 2011, 04:40 PM
1) I left this part out before. my bad

#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>


@interface FirstView : UIViewController <AVAudioPlayerDelegate> {

AVAudioPlayer *myMusic;
CGPoint *location1;
UITouch *touch;
IBOutlet UIImageView *image1;
NSString *myString;
IBOutlet UIButton *button1;
IBOutlet UIButton *button2;
}
- (IBAction) button1press;
- (IBAction) button2press;


@property (nonatomic, retain) IBOutlet UIImageView *image1;
@property (nonatomic, retain) IBOutlet UIButton *button1;
@property (nonatomic, retain) IBOutlet UIButton *button2;

@property(nonatomic, retain) AVAudioPlayer* myMusic;


@end


or did you mean that I should have put this...

NSString *myString=[[NSString alloc] initWithString:@"sound1"];

in this method...

if(CGRectContainsPoint(image1.frame, location1))
{ [image1 setHighlighted:YES];
NSString *path = [[NSBundle mainBundle] pathForResource:@"sound1" ofType:@"wav"];
myMusic=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[myMusic play];

}else {
[image1 setHighlighted:NO];
}

Neither, really. You've declared an ivar (instance variable) by putting that line (I've highlighted it in green) into the .h. But when you have a line like this in your method:
-(IBAction)button1press {
NSString *myString=[[NSString alloc] initWithString:@"sound1"];
}

you override the scope of the ivar with a variable of scope local only to that method. You should be getting warnings around this code. Don't ignore them. Plus, when you alloc something, it's your responsibility to release it as well. Make sure you think about when/where that should be done.

2) Monkey see, Monkey do. I found some code on the internet where someone did it like that. Clearly not the right approach. :)
Well, at least you're admitting where the fault is. :) Copy-and-paste is not programming. In general, if you don't understand why you're doing something, you probably shouldn't be doing it. Step back and make sure you're comfortable with the fundamentals.

nickculbertson
Jan 10, 2011, 05:17 PM
Thanks Dejo!

I have 2 apps "in review" right now with several ivar warnings. It'll be interesting to see if they let them slide.


I got it figured out now. I added a UILabel like an on screen NSLog.


took out the .h string

in the .m

- (IBAction)button1press:(id)sender{
label1.text = @"ONE";
}
- (IBAction)button2press:(id)sender{
label1.text = @"TWO";
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location1 = [touch locationInView:touch.view];

if(CGRectContainsPoint(image1.frame, location1))
{ if (label1.text == @"ONE")
{[image1 setHighlighted:YES];
NSString *path = [[NSBundle mainBundle] pathForResource:@"sound1" ofType:@"wav"];
myMusic=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[myMusic play];}
else if (label1.text == @"TWO"){[image1 setHighlighted:YES];
NSString *path = [[NSBundle mainBundle] pathForResource:"sound2" ofType:@"wav"];
myMusic=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[myMusic play];}

}else {
[image1 setHighlighted:NO];
}


Thanks Again,
Nick

dejo
Jan 10, 2011, 05:39 PM
if (label1.text == @"ONE")
is not the proper way to check NSStrings for equality.

nickculbertson
Jan 10, 2011, 05:51 PM
is not the proper way to check NSStrings for equality.

hmmm, I will take a closer look at it later but for now it does what I need with no warnings or errors. I click button1, label1 reads "ONE", sound1 plays with image1 touch.

Thanks,
Nick

todizara
Feb 3, 2011, 12:08 AM
hello! I want to create a button whose name is stored in a NSString as:

NSString buttonname;

and to declared the button, I have no idea. I want to do:

UIButton buttonname *;