UIButton to change pathForResource

Discussion in 'iOS Programming' started by nickculbertson, Jan 10, 2011.

  1. macrumors regular

    nickculbertson

    Joined:
    Nov 19, 2010
    Location:
    Nashville, TN
    #1
    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".

    Code:
    -(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
     
  2. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    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.
     
  3. thread starter macrumors regular

    nickculbertson

    Joined:
    Nov 19, 2010
    Location:
    Nashville, TN
    #3

    So, is this getting close?

    .h
    Code:
    
    NSString *myString;
    
    
    .m
    Code:
    -(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
     
  4. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #4
    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:?
     
  5. thread starter macrumors regular

    nickculbertson

    Joined:
    Nov 19, 2010
    Location:
    Nashville, TN
    #5
    1) I left this part out before. my bad

    Code:
    #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...

    Code:
     NSString *myString=[[NSString alloc] initWithString:@"sound1"];
    in this method...

    Code:
    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) Monkey see, Monkey do. I found some code on the internet where someone did it like that. Clearly not the right approach. :)

    Thanks,
    Nick
     
  6. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #6
    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:
    Code:
    -(IBAction)button1press {
        [COLOR="SeaGreen"]NSString *myString=[[NSString alloc] initWithString:@"sound1"];[/COLOR]
    }
    
    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.

    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.
     
  7. thread starter macrumors regular

    nickculbertson

    Joined:
    Nov 19, 2010
    Location:
    Nashville, TN
    #7
    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.

    Code:
    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
     
  8. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #8
    Code:
    if (label1.text == @"ONE")
    is not the proper way to check NSStrings for equality.
     
  9. thread starter macrumors regular

    nickculbertson

    Joined:
    Nov 19, 2010
    Location:
    Nashville, TN
    #9
    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
     
  10. macrumors newbie

    Joined:
    Dec 17, 2010
    #10
    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 *;
     

Share This Page