Why does the AVAudioPlayer stop method not work when switching views - iphone

I have an iphone app that displays images and plays audio selected from a main menu.
The user clicks on a button to select the image/audio combo they want. The code to switch the views with animation works fine.
All of the code to display the image, play, pause, scrub, and stop the audio while in the new view works fine too.
However, when the users clicks the Main Menu button I want the playing audio to stop. I am using viewWillDisappear:(BOOL)animated to call the stop method:
-(void)viewWillDisappear:(BOOL)animated {
audioPlayer.stop;
[super viewWillDisappear: animated];}
This code doesn't stop the sound when the user switches back to the main menu view. Is there a better way to do this? Am I doing something wrong?
Here is the code from the entire class where the snippet above resides:
#import "twelthPoem.h"
UIImageView *largeImageView;
#implementation twelthPoem
-(void)resetControls
{
audioPlayer.currentTime = 0;
scrubber.value = 0;
[playButton setImage:[UIImage imageNamed:#"play_HL.png"]
forState:UIControlStateNormal];
}
-(void)play:(id)sender {
if (! audioPlayer.playing) {
audioPlayer.play;
[playButton setImage:[UIImage imageNamed:#"pauseHL.png"] forState:UIControlStateNormal];
}
else {
audioPlayer.pause;
[playButton setImage:[UIImage imageNamed:#"play_HL.png"] forState:UIControlStateNormal];
}
[self becomeFirstResponder];
}
-(void)stop:(id)sender {
audioPlayer.stop;
[self resetControls];
}
-(void)changeVolume:(id)sender {
audioPlayer.volume = volume.value;
[self becomeFirstResponder];
}
-(void)scrub:(id)sender {
if (audioPlayer.playing) {
audioPlayer.pause;
audioPlayer.currentTime = scrubber.value;
audioPlayer.play;
}
else
audioPlayer.currentTime = scrubber.value;
[self becomeFirstResponder];
}
-(void)createControls {
//play/pause button
playButton = [UIButton buttonWithType:UIButtonTypeCustom];
[playButton setFrame:CGRectMake(60,405,80,20)];
[playButton setImage:[UIImage imageNamed:#"play_HL.png"] forState:UIControlStateNormal];
[playButton addTarget:self action:#selector(play:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:playButton];
//stop button
stopButton = [UIButton buttonWithType:UIButtonTypeCustom];
[stopButton setFrame:CGRectMake(180,405,80,20)];
[stopButton setImage:[UIImage imageNamed:#"stopHL.png"] forState:UIControlStateNormal];
[stopButton addTarget:self action:#selector(stop:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:stopButton];
//volume control
volume = [[UISlider alloc] initWithFrame:CGRectMake(10,445,145,20)];
[volume addTarget:self action:#selector(changeVolume:)
forControlEvents:UIControlEventValueChanged];
volume.minimumValue = 0.0;
volume.maximumValue = 1.0;
volume.value = audioPlayer.volume;
volume.continuous = YES;
[self.view addSubview:volume];
//scrubber control
scrubber = [[UISlider alloc] initWithFrame:CGRectMake(165,445,145,20)];
[scrubber addTarget:self action:#selector(scrub:)
forControlEvents:UIControlEventValueChanged];
scrubber.minimumValue = 0.0;
scrubber.maximumValue = audioPlayer.duration;
scrubber.value = audioPlayer.currentTime;
scrubber.continuous = NO;
[self.view addSubview:scrubber];
}
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
switch (event.subtype)
{
case UIEventSubtypeRemoteControlTogglePlayPause:
[self play:nil];
break;
case UIEventSubtypeRemoteControlNextTrack:
//do nothing
break;
case UIEventSubtypeRemoteControlPreviousTrack:
//do nothing
break;
}
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
-(void)viewDidLoad {
//for scrolling the image
[super viewDidLoad];
CGRect scrollFrame = CGRectMake(0,40,320,350);
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
scrollView.minimumZoomScale = 1.0;
scrollView.maximumZoomScale = 1.5;
scrollView.delegate = self;
UIImage *bigImage = [UIImage imageNamed:#"birches.png"];
largeImageView = [[UIImageView alloc] initWithImage:bigImage];
[scrollView addSubview:largeImageView];
scrollView.contentSize = largeImageView.frame.size; //important!
[self.view addSubview:scrollView];
[scrollView release];
//for playing the recording
NSString *filePath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"birches_final_mp3.mp3"];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSError *error = nil;
OSStatus status = AudioSessionInitialize(NULL, NULL, NULL, NULL);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
status = AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,
sizeof (sessionCategory),
&sessionCategory);
AudioSessionSetActive(YES);
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
error:&error];
if (error )
NSLog(#"An error occurred: %#",error);
else
{
audioPlayer.volume = 0.3;
[audioPlayer prepareToPlay];
[self createControls];
}
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return largeImageView;
}
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
interrupted = audioPlayer.playing;
}
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player
{
if (interrupted)
audioPlayer.play;
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player
successfully:(BOOL)flag
{
[self resetControls];
}
-(void)viewWillDisappear:(BOOL)animated {
audioPlayer.stop;
[super viewWillDisappear: animated];
}
- (void)dealloc {
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[scrubber release];
[volume release];
[audioPlayer release];
[super dealloc];
}
#end

You call methods in objective-c using the following syntax.
[audioPlayer stop];
audioPlayer.stop will not work.
Same goes for other places as well.

audioPlayer.stop will not work mostly because it needs an expression after it, e.g. audioPlayer.stop = //expression, stop is a bool, so you can say audioPlayer.stop = YES; or [audioPlayer stop];

Related

iOS and Objective-C: why does my UIWebView gets fullscreen when I click a link on it?

At first, sorry for my bad English, I'm just learning it. Im relatively new at Objective-C and I'm using FBConnect bundle to link my app to Facebook. All it's working correctly, but when I click a link into the UIWebView (the Facebook login button, for example), my UIWebView gets fullscreen and hides my close button (a little 'x' button in the top right of the UIWebView, called here "_closeButton").
Here's the code:
The "init" method:
- (id)init {
if ((self = [super initWithFrame:CGRectZero])) {
_delegate = nil;
_loadingURL = nil;
_showingKeyboard = NO;
self.backgroundColor = [UIColor clearColor];
self.autoresizesSubviews = NO;
//self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.contentMode = UIViewContentModeRedraw;
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(kPadding, kPadding, 480, 480)];
_webView.delegate = self;
//_webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:_webView];
//UIImage* closeImage = [UIImage imageNamed:#"FBDialog.bundle/images/close.png"];
UIImage* closeImage = [UIImage imageNamed:#"close"];
UIColor* color = [UIColor colorWithRed:255.0/255 green:/*184.0*/0.0/255 blue:/*216.0*/0.0/255 alpha:1];
_closeButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
[_closeButton setImage:closeImage forState:UIControlStateNormal];
[_closeButton setTitleColor:color forState:UIControlStateNormal];
[_closeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[_closeButton addTarget:self action:#selector(cancel)
forControlEvents:UIControlEventTouchUpInside];
// To be compatible with OS 2.x
#if __IPHONE_OS_VERSION_MAX_ALLOWED <= __IPHONE_2_2
_closeButton.font = [UIFont boldSystemFontOfSize:12];
#else
_closeButton.titleLabel.font = [UIFont boldSystemFontOfSize:12];
#endif
_closeButton.showsTouchWhenHighlighted = YES;
_closeButton.autoresizingMask = UIViewAutoresizingFlexibleRightMargin
| UIViewAutoresizingFlexibleBottomMargin;
[self addSubview:_closeButton];
NSLog(#"close");
_spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:
UIActivityIndicatorViewStyleWhiteLarge];
_spinner.autoresizingMask =
UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin
| UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[self addSubview:_spinner];
_modalBackgroundView = [[UIView alloc] init];
}
return self;
}
The delegate of the WebView (I suspect here's where I need to do the trick)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSURL* url = request.URL;
if ([url.scheme isEqualToString:#"fbconnect"]) {
if ([[url.resourceSpecifier substringToIndex:8] isEqualToString:#"//cancel"]) {
NSString * errorCode = [self getStringFromUrl:[url absoluteString] needle:#"error_code="];
NSString * errorStr = [self getStringFromUrl:[url absoluteString] needle:#"error_msg="];
if (errorCode) {
NSDictionary * errorData = [NSDictionary dictionaryWithObject:errorStr forKey:#"error_msg"];
NSError * error = [NSError errorWithDomain:#"facebookErrDomain"
code:[errorCode intValue]
userInfo:errorData];
[self dismissWithError:error animated:YES];
} else {
[self dialogDidCancel:url];
}
} else {
[self dialogDidSucceed:url];
}
return NO;
} else if ([_loadingURL isEqual:url]) {
return YES;
} else if (navigationType == UIWebViewNavigationTypeLinkClicked) {
if ([_delegate respondsToSelector:#selector(dialog:shouldOpenURLInExternalBrowser:)]) {
if (![_delegate dialog:self shouldOpenURLInExternalBrowser:url]) {
return NO;
}
}
[[UIApplication sharedApplication] openURL:request.URL];
return NO;
} else {
return YES;
}
}
And the show method (called when I need to show the Web View)
- (void)show {
NSLog(#"Cuantas veces me ves?");
[self load];
[self sizeToFitOrientation:NO];
CGFloat innerWidth = self.frame.size.width - (kBorderWidth+1)*2;
[_closeButton sizeToFit];
_closeButton.frame = CGRectMake(
2,
2,
29,
29);
_webView.frame = CGRectMake(
kBorderWidth+1,
kBorderWidth+1,
innerWidth,
self.frame.size.height - (1 + kBorderWidth*2));
[_spinner sizeToFit];
[_spinner startAnimating];
_spinner.center = _webView.center;
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window) {
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}
_modalBackgroundView.frame = window.frame;
[_modalBackgroundView addSubview:self];
[window addSubview:_modalBackgroundView];
[window addSubview:self];
[self dialogWillAppear];
self.transform = CGAffineTransformScale([self transformForOrientation], 0.001, 0.001);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kTransitionDuration/1.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(bounce1AnimationStopped)];
self.transform = CGAffineTransformScale([self transformForOrientation], 1.1, 1.1);
[UIView commitAnimations];
[self addObservers];
}
Googling the problem, I found that this could be the Default behaviour of the UIWebView. How can I change it to make all my WebViews of the same size than the first one?
Thanks in advance!
== EDIT ==
Still don't know why is my UIWebView acting like this, or how to solve it, but since the code is part of the FBConnect Bundle, I suppose I shouldn't edit it too much. I just created programmatically a new close button on the top and that's all. But I'll let the question open if someone knows how to solve it. Thanks to Leo Natan for his help.

MPMoviePlayerController - Video stops when I change contentURL

While a movie is playing, if I change my contentURL the movie stops playing and the view is removed.
I've tried the solution here but it still doesn't work.
Here's my code to play the movie:
- (void) playMovie:(NSURL *)moviePath{
theMovie = [[MPMoviePlayerController alloc] initWithContentURL: moviePath];
UIView * movieView = [theMovie view];
[movieView setFrame: CGRectMake(0, 0, 480, 320)];
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
CGAffineTransform landscapeTransform;
landscapeTransform = CGAffineTransformMakeRotation(degreesToRadian(90));
landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 80, 80);
[movieView setTransform: landscapeTransform];
self.theMovie.scalingMode = MPMovieScalingModeAspectFit;
self.theMovie.fullscreen = TRUE;
self.theMovie.controlStyle = MPMovieControlStyleNone;
[self performSelector:#selector(showCtrlsOnTouch) withObject:NULL afterDelay:0.1];
[self.theMovie prepareToPlay];
int a = currentMovie;
int b = [self.tableDataSource count] - 1;
if(a < b)
{
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
nextButton.frame = CGRectMake(360.0, 138.0, 100.0, 44.0);
[nextButton setTitle:#"Next" forState:UIControlStateNormal];
[self.theMovie.view addSubview:nextButton];
[nextButton addTarget:self action:#selector(playNextMovie:) forControlEvents:UIControlEventTouchUpInside];
}
if(currentMovie > 0)
{
UIButton *previousButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
previousButton.frame = CGRectMake(40.0, 138.0, 100.0, 44.0);
[previousButton setTitle:#"Prev" forState:UIControlStateNormal];
[self.theMovie.view addSubview:previousButton];
[previousButton addTarget:self action:#selector(playPreviousMovie:) forControlEvents:UIControlEventTouchUpInside];
}
[[[UIApplication sharedApplication] keyWindow] addSubview: movieView];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(movieFinishedCallback:)
name: MPMoviePlayerPlaybackDidFinishNotification
object: self.theMovie];}
And here's my code to switch the movie:
- (void) playNextMovie:(id) sender{
currentMovie++;
NSDictionary *dictionary = [self.tableDataSource objectAtIndex:currentMovie];
NSString *videoString = [NSString stringWithFormat:#"%#", [dictionary objectForKey:#"videoFile"]];
NSString *videoPath = [[NSBundle mainBundle] pathForResource:videoString ofType:#"m4v"];
NSLog(#"Video Path: %#", videoPath);
NSURL *moviePath = [NSURL fileURLWithPath: videoPath];
self.theMovie.contentURL = moviePath;
[self.theMovie prepareToPlay];}
Thanks for any help.
It is totally normal for the player to stop playing once a new contentURL is supplied.
The MPMoviePlayerController.view however is usually not being removed automatically. I am assuming that you forgot about one of your notification handlers doing something like that for you.

Pause the Views from Updating

Want to pause the multiple views from updating when Pause button is pressed
In h file
#property BOOL appIsPaused;
In m file
#synthesize appIsPaused;
-(void)playpauseAction:(id)sender
{
if
([audioPlayer isPlaying]){
[sender setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateSelected];
[audioPlayer pause];
appIsPaused = YES;
} else {
[sender setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal];
[audioPlayer play];
appIsPaused = NO;
[self performSelector:#selector(displayviewsAction:) withObject:nil afterDelay:11.0];
}
}
- (void)displayviewsAction:(id)sender
{
FirstViewController *viewController = [[FirstViewController alloc] init];
viewController.view.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:viewController.view];
[self.view addSubview:toolbar];
[self performSelector:#selector(secondViewController) withObject:nil afterDelay:23];
[viewController release];
}
-(void)secondViewController {
SecondViewController *secondController = [[SecondViewController alloc] init];
secondController.view.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:secondController.view];
[self.view addSubview:toolbar];
[self performSelector:#selector(ThirdviewController) withObject:nil afterDelay:27];
[secondController release];
}
and it goes on like this for multiple views.
Any ideas how to pause views from updating whenever pause button is pressed.
Instead of using performSelector after delay, you should consider using a NSTimer.
Like this:
Declare a NSTimer *timer ivar.
Declare a NSUInteger viewControl;
Set viewControl to 0;
On the play part of the method add this line:
timer = [NSTimer scheduledTimerWithTimeInterval:11 target:self selector:#selector(tick) userInfo:nil repeats:YES];
-(void)tick
{
switch(viewControl)
{
case 0:
[self performSelector:#selector(firstViewController) withObject:nil];
break;
case 1:
[self performSelector:#selector(secondViewController) withObject:nil];
break;
case 2:
[self performSelector:#selector(thirdViewController) withObject:nil];
break;
.
.
.
default:
break;
}
viewControl++;
if(viewControl > MAX_VIEWS)
{
viewControl = 0;
}
}
And add this line on pause action:
[timer invalidate]
It is also cleaner and let you have more control over your code.
Hope it helps.

Play/stop UIButton toggle using selected property for state not working

I can't see what the problem is with my code. Nothing happens when I press the button, like as if the default state wasn't even set, which is weird because we can't do something playButton.state = UIControlStateNormal since the state property is read-only.
This is my code:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// ...
playButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
playButton.frame = CGRectMake(100, 500, 100, 50);
[playButton setTitle:#"play" forState: UIControlStateNormal];
[playButton setTitle:#"stop" forState: UIControlStateSelected];
playButton.exclusiveTouch = YES;
playButton.selected = NO;
[playButton addTarget:self action:#selector(play) forControlEvents:UIControlEventTouchUpInside];
and
- (void) play {
if (playButton.state == UIControlStateNormal) {
playButton.selected = YES;
CABasicAnimation *maskAnim = [CABasicAnimation animationWithKeyPath:#"position.x"];
maskAnim.byValue = [NSNumber numberWithFloat:diagramWidth];
maskAnim.repeatCount = HUGE_VALF;
maskAnim.duration = 1.750f;
[self.maskLayer addAnimation:maskAnim forKey:#"position.x"];
self.diagramLayer.mask = maskLayer;
[backImageLayer addSublayer: self.diagramLayer];
[audioPlayerNormal play];
[moviePlayerNormal play];
}
else if (playButton.state == UIControlStateSelected) {
playButton.selected = NO;
[self.maskLayer removeAnimationForKey:#"position.x"];
self.diagramLayer.mask = nil;
[audioPlayerNormal stop];
[moviePlayerNormal stop];
}
}
The following code should do the job.
- (void) play {
if (playButton.selected == NO) {
CABasicAnimation *maskAnim = [CABasicAnimation animationWithKeyPath:#"position.x"];
maskAnim.byValue = [NSNumber numberWithFloat:diagramWidth];
maskAnim.repeatCount = HUGE_VALF;
maskAnim.duration = 1.750f;
[self.maskLayer addAnimation:maskAnim forKey:#"position.x"];
self.diagramLayer.mask = maskLayer;
[backImageLayer addSublayer: self.diagramLayer];
[audioPlayerNormal play];
[moviePlayerNormal play];
}
else {
[self.maskLayer removeAnimationForKey:#"position.x"];
self.diagramLayer.mask = nil;
[audioPlayerNormal stop];
[moviePlayerNormal stop];
}
playButton.selected = !playButton.selected;
}

How to change background image of a button and get it updated instantly?

Im developing a memory game. As i click on a button I want the background to switch. When I click on the card the second time i want the background to switch for a second and then go back to the original (if it wasnt the correct card). But the background of the buttons are not changed until i return from the method (buttonPressed). Why isnt it changed instantly? Please help me! :)
Here is the class that i am working with:
#import "Button.h"
#import <UIKit/UIKit.h>
#import <AVFoundation/AVAudioPlayer.h>
#class ZogajAppDelegate;
#interface PairPlayPlayViewController : UIViewController <AVAudioPlayerDelegate> {
ZogajAppDelegate *appDelegate;
AVAudioPlayer *av;
Boolean isPairActive;
Button *firstButton;
Button *secondButton;
}
#property (nonatomic, retain) AVAudioPlayer *av;
#property (nonatomic, retain) Button *firstButton;
#property (nonatomic, retain) Button *secondButton;
- (void)buttonPressed:(id)sender;
- (void)secondCard;
#end
and the .m file:
#import "PairPlayPlayViewController.h"
#import "ZogajAppDelegate.h"
#import "Button.h"
#import "AVFoundation/AVAudioPlayer.h"
#implementation PairPlayPlayViewController
#synthesize av, firstButton, secondButton;
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *newAudioFile = [[NSBundle mainBundle] pathForResource:#"double_card" ofType:#"mp3"];
NSString *newAudioFile2 = [[NSBundle mainBundle] pathForResource:#"right_sound" ofType:#"mp3"];
av = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:NULL];
[av prepareToPlay];
[av initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile2] error:NULL];
[av prepareToPlay];
//av = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:NULL];
//[av prepareToPlay];
isPairActive = FALSE;
appDelegate = (ZogajAppDelegate *)[[UIApplication sharedApplication] delegate];
int position;
for(int i = 0; i < ((appDelegate.numberOfPairs*2)/5); i++){
for (int j = 0; j<5 ;j++){
Button *button = [[Button alloc] init];
//Sätter bild nummer..
position = (arc4random() % [appDelegate.cardsInPlay count]);
button.picNumber = [[appDelegate.cardsInPlay objectAtIndex:position]intValue];
NSLog(#"%d", button.picNumber);
[appDelegate.cardsInPlay removeObjectAtIndex:position];
button.frame = CGRectMake( 3 + (65 * j), 5 + (65 * i), 55, 55);
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.clipsToBounds = YES;
[button setBackgroundImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
}
for (int j = 0; j<((appDelegate.numberOfPairs*2) % 5) ;j++){
Button *button = [[Button alloc] init];
//Sätter bild nummer..
position = (arc4random() % [appDelegate.cardsInPlay count]);
button.picNumber = [[appDelegate.cardsInPlay objectAtIndex:position]intValue];
NSLog(#"%d", button.picNumber);
[appDelegate.cardsInPlay removeObjectAtIndex:position];
button.frame = CGRectMake( 3 + (65 * j), 5 + (65 * ((appDelegate.numberOfPairs*2)/5) + 1), 55, 55);
//button.imageView.contentMode = UIViewContentModeScaleAspectFit;
//button.imageView.clipsToBounds = YES;
[button setBackgroundImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonPressed:)
forControlEvents:UIControlEventAllTouchEvents];
[self.view addSubview:button];
}
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
-(void)buttonPressed:(id)sender {
Button *button = [[Button alloc] init];
button = sender;
NSLog(#"%d och spela upp ljud", button.picNumber);
NSString *newAudioFile = [[NSBundle mainBundle] pathForResource:#"double_card" ofType:#"mp3"];
[av initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:NULL];
[av play];
[button setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:#"%d.png",button.picNumber]] forState:UIControlStateNormal];
[self.view addSubview:button];
[NSThread sleepForTimeInterval:1.0];
if(isPairActive == FALSE){
isPairActive = TRUE;
firstButton = button;
}
else {
secondButton = button;
[self secondCard];
}
return;
}
- (void)secondCard {
[NSThread sleepForTimeInterval:1.0];
NSString *newAudioFile = [[NSBundle mainBundle] pathForResource:#"double_card" ofType:#"mp3"];
isPairActive = FALSE;
if([appDelegate.dictionary objectForKey:[NSString stringWithFormat:#"%d",secondButton.picNumber]] == [NSString stringWithFormat:#"%d",firstButton.picNumber]){
NSString *newAudioFile2 = [[NSBundle mainBundle] pathForResource:#"right_sound" ofType:#"mp3"];
[av initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile2] error:NULL];
[av play];
}
else {
[firstButton setBackgroundImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
[secondButton setBackgroundImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
[av initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:NULL];
[av play];
}
return;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
[av release];
[firstButton release];
[secondButton release];
}
#end
In buttonPressed: change the background, set an NSTimer to call you back, and return. In the NSTimer callback, set the background back to what you want.
Drawing doesn't happen at the moment you ask for it. That would give you horrible performance. All drawing is merged into the draw portion of the run loop. You won't get to that portion until you return from this IBAction method.
As you already know, the image will be changed after returning from the method. That's it.
You have to return from the method, so you have to change the image, perform selector that executes the rest of code you want to perform and return from the method.
UIKit can run only on main thread, so you have to return from the method, that's blocking it, and it will execute GUI manipulations then.
EDIT:
Instead of telling NSThread to sleep, perform the selector with delay.