How to pause program execution when pause button is pressed - iphone

I want in this action whenever pause button is pressed it should pause the program execution as well because right now when i pause the audio file it still keeps on displaying views one after the other. I want that to be paused as well.
-(void)playpauseAction:(id)sender
{
if
([audioPlayer isPlaying]){
[sender setImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateSelected];
[audioPlayer pause];
} else {
[sender setImage:[UIImage imageNamed:#"pause.png"] forState:UIControlStateNormal];
[audioPlayer play];
[self performSelector:#selector(displayviewsAction:) withObject:nil afterDelay:11.0];
}
}
Anyone know how i can pause the program execution as well.

You can use this [NSThread sleepForTimeInterval:[[NSDate date] timeIntervalSince1970]];
but you will not be able to resume it because your main thread sleeps so you will not receive the touch.
And I also think that your app will not be approved in store.
What I recommend is to use NSTimer to trigger the action and when you press pause just invalidate the timer, when you press play crate a new timer and fire it.

Related

IOS Audio won't work after stop idle awhile

My application worked fine when I play and stop the music at the start of the running but when I later stopped the music and let the application idle for quite some time and clicked the play button, the application didn't output any warning and no music is played even the log output my music is now playing. I have no idea what is the error that leads to this as nothing is wrong. Is it a common behavior in IOS simulator?
This is my audio code just in case.
-(void)musicIsPlaying:(id)sender
{
AVAudioPlayer *theAudio = [sender objectForKey:#"audio"];
UIButton *btn = [sender objectForKey:#"button"];
if (btn.selected == TRUE)
{
[btn setTitle:#"Stop" forState:UIControlStateNormal];
[btn setSelected:FALSE];
if(theAudio.isPlaying == NO)
{
[theAudio prepareToPlay];
[theAudio play];
NSLog(#"music playing");
}
}
else
{
[btn setTitle:#"Play" forState:UIControlStateNormal];
[btn setSelected:TRUE];
if(theAudio.isPlaying==YES)
{
[theAudio stop];
NSLog(#"music stop playing");
}
}
}
You should call method to resume your play when Application becomes active. So, write your code to resume your play in Appdelegate.
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
you need to Declare AVAudioPlayer in Interface
#interface AudioViewController ()
{
AVAudioPlayer *theAudio;
}
#end
the use this "theAudio" object in your method(musicIsPlaying)..like
theAudio = [sender objectForKey:#"audio"];
Hope..it will work for you...

Getting wrong playback state in MP Music Player Controller in ios 5

i am getting wrong playback state in MP music player.
while playing a song i am getting pause state.
My app is working fine in ios 4.but i am having this issue in ios 5.
can anybody Help me ??
My code is here.
[musicPlayer stop];
if (userMediaItemCollection)
{
userMediaItemCollection=nil;
}
musicPlayer.nowPlayingItem=nil;
userMediaItemCollection=[MPMediaItemCollection collectionWithItems:[mediaItemCollection items]];
[musicPlayer setQueueWithItemCollection:userMediaItemCollection];
[musicPlayer setNowPlayingItem:
[[userMediaItemCollectionitems]objectAtIndex:indexOfCurrentObject]];
[self enablePrevAndNextButtons];
[musicPlayer play];
}
-(void)playbackStateDidChanged:(NSNotification *)notification
{
if (musicPlayer.playbackState!=MPMusicPlaybackStatePlaying)
{
[playPauseButton setBackgroundImage:[UIImage imageNamed:#"play_iPad.png"] forState:UIControlStateNormal];
}
else if(musicPlayer.playbackState==MPMusicPlaybackStatePlaying)
{
[playPauseButton setBackgroundImage:[UIImage imageNamed:#"pause_iPad.png"] forState:UIControlStateNormal];
}
I have also reported this bug to Apple. I was able to reproduce it 100% of the time by doing the following:
Launch application that uses MPMusicPlayerController.
Launch the "Music" App.
Hit Play, Skip, Skip, Pause, Play, Pause
Open the original application and the MPMusicPlaybackState of MPMusicPlayerController will be incorrect.
None of the proposed solutions here worked for me. The solution that did work was to keep track of when the bug was occurring and updating the UI specially in these cases.
When the UIApplicationDidBecomeActiveNotification notification is received (see matbur post for more details on this), see if audio is actually not playing when the MPMusicPlaybackState said it was:
-(BOOL) isPlaybackStateBugActive {
MPMusicPlaybackState playbackState = self.musicPlayer.playbackState;
if (playbackState == MPMusicPlaybackStatePlaying) {
AudioSessionInitialize (NULL, NULL, NULL, NULL);
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
AudioSessionSetActive (true);
UInt32 audioIsPlaying;
UInt32 size = sizeof(audioIsPlaying);
AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &size, &audioIsPlaying);
if (!audioIsPlaying){
NSLog(#"PlaybackState bug is active");
return YES;
}
}
return NO;
}
Don't forget to import the AudioToolbox framework.
None of these workarounds fix the issue for my app. It is a bug in iOS, and my app will never function properly until Apple fixes it.
I have a music player with a play/pause button. When music is playing, the button shows the "pause" icon. When music is paused, the button shows the "play" icon - just like all music apps. I can replicate the bug at any time by doing the following:
1. Play music in my app (the play/pause button shows the "pause" icon correctly)
2. Background my app and lock my phone for ~10 minutes
3. Double tap home and hit the pause button from the iPod controls
4. Unlock my phone and open my app again
5. Music will be stopped, but my app still shows the "pause" icon when it should so "play"
I've done extensive debugging and logging to ensure that the method that updates my play/pause button is always called when my application becomes active. The issue is that when I re-enter my app, the playback state of MPMusicPlayer is still set to MPMusicPlaybackStatePlaying even when music is stopped/paused.
I filed a bug report for this about a year ago and haven't heard anything from Apple. If someone else would file one it would be greatly appreciated.
I have the same problem but when I play/pause many times when my app is in background, I reported the bug to Apple and hope to get an amswer soon, I want to know if my coding is wrong or there is an API problem. If this was the error you were having, this may be helpful. I came to a workaround which even though isnt the best solution, for my app is acceptable:
In the viewDidLoad, add this:
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver: self
selector: #selector (handle_ApplicationDidBecomeActive:)
name: UIApplicationDidBecomeActiveNotification
object: nil];
Then, create a handle_ApplicationDidBecomeActive method, and add this:
- (void) handle_ApplicationDidBecomeActive: (id) notification
{
if (musicPlayer.playbackState!=MPMusicPlaybackStatePlaying)
{
[playPauseButton setBackgroundImage:[UIImage imageNamed:#"play_iPad.png"] forState:UIControlStateNormal];
[musicPlayer pause];
}
else if(musicPlayer.playbackState==MPMusicPlaybackStatePlaying)
{
[playPauseButton setBackgroundImage:[UIImage imageNamed:#"pause_iPad.png"] forState:UIControlStateNormal];
[musicPlayer pause];
}
}
(dont put this code inside your playbackStateDidChanged method as this may generate an endless loop)
This will sync the state of your buttons and music player to the one reported by the API. in the cases in which there is a coincidence, there will be no impact of any type, in the other cases, the player will pause/play accordingly.
I experienced the same problem with the release of iOS 5. I found that the playbackState property does get updated, but after a delay, so it's not yet set when your playbackStateDidChanged method runs.
My workaround was to set my own instance variable called musicPlayerRecentlyStartedPlaying whenever I start playback. Then I use a method called from a timer to check both that variable and the playbackState property to find out if the player is really playing:
- (void)playMusic {
[self.musicPlayer play];
self.musicPlayerRecentlyStartedPlaying = TRUE;
self.musicControlsUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateMusicControls:) userInfo:nil repeats:TRUE];
}
- (void)stopMusic {
[self.musicPlayer stop];
self.musicPlayerRecentlyStartedPlaying = FALSE;
[self.musicControlsUpdateTimer invalidate];
}
- (void)updateMusicControls:(NSTimer *)timer {
BOOL playing = (([self.musicPlayer playbackState] == MPMusicPlaybackStatePlaying)&&(self.musicPlayer.nowPlayingItem));
if (!playing) {
// check to see if we recently started playing
if (self.musicPlayerRecentlyStartedPlaying) {
playing = TRUE;
}
} else {
// once the property is updated, we no longer need this
self.musicPlayerRecentlyStartedPlaying = FALSE;
}
}
You might not need to call updateMusicControls from a timer, but I do because I'm also updating the position of a progress bar as the music plays.
This code using when previous Button click Previous song will be play
- (IBAction)playPreviousSongInList:(id)sender {
static NSTimeInterval skipToBeginningOfSongIfElapsedTimeLongerThan = 3.5;
NSTimeInterval playbackTime = self.musicPlayer.currentPlaybackTime;
if (playbackTime <= skipToBeginningOfSongIfElapsedTimeLongerThan) {
[self.musicPlayer skipToPreviousItem];
} else {
[self.musicPlayer skipToBeginning];
}
}

Time elapsed button in the iphone sdk

How do you create a time elapsed button in objective-c iphone SDK. To be a little more specific, this button will show in text how much time has elapsed since you've been holding the button. So for the time to elapse you must still have a finger on the button, not letting go. Once you let go the timer should restart. Note: For the iphone, not mac.
Use these two methods for buttons events. touchDown is called when you press the button and touchUp will be called when you lift your finger from the button. Calculate the time difference between these two methods. Also you can start timer in touchDown and stop/restart it in touchUp.
//connect this action with Touch up inside
- (IBAction)touchUp:(id)sender {
NSLog(#"up");
}
//connect this to tocuh down
- (IBAction)touchDown:(id)sender{
NSLog(#"down");
}
first, set an int variable at your header file
#property int timerCount;
#property (nonatomic, strong)NSTimer *yourTimer;
dont forget to synthesize it at the implementation file
(if you're still on lower SDK, you can change "strong" to "retain")
and then make the button and it's function
UIButton *yourButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
[yourButton setTag:1];
[yourButton setBackgroundColor:[UIColor redColor]];
[yourButton addTarget:self action:#selector(buttonHoldDown) forControlEvents:UIControlEventTouchDown];
[yourButton addTarget:self action:#selector(buttonRelease) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:yourButton];
this way, you've add a button at x:0 y:0 on your view with red color, containing two action target which is touch down and up inside
when you touch the button, the buttonHoldDown function is triggered, and when u release the button, the buttonRelease function is triggered
and then, fill the function
-(void)buttonHoldDown
{
yourTimer = [NSTimer timerWithTimeInterval:1 target:self selector:#selector(timerStart) userInfo:nil repeats:NO];
timerCount = 0;
}
-(void)buttonHoldUp
{
NSLog(#"the timer stops at %d seconds", timerCount);
timerCount = 0;
[yourTimer invalidate];
}
-(void)timerStart
{
timerCount++;
}
this way, when you touch the button, the program creates a timer and revalue the int timerCount to 0, which will be increased as the timer ticks in the "timerStart" function.
as you release the button, the function will track your current timerCount record and print it on the system, and then stop the timer

iphone button pressed for 3 seconds goes to a different view

I have a button in my app that when pressed goes to a view
but I need that when pressed for 3 seconds it would go to a different view,
like when you are on ipad on safari and you keep pressed the url, and it shows a pop up with copy etc,
but I need that when pressed for 3 second it goes to another view...
hope this makes sense, I will explain better if not understood,
thank you so much!
pd, also how to make it show the pop up style window?
cheers!
Try setting an NSTimer property in your view controller. When the button's pressed, create the timer and assign it to your property. You can detect that moment with this:
[button addTarget:self action:#selector(startHoldTimer) forControlEvents:UIControlEventTouchDown];
and assign with this:
-(void) startHoldTimer {
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:#selector(goToNewView:) userInfo:nil repeats:NO];
}
Then set an action to run on a canceled touch, or a touch up inside:
[button addTarget:self action:#selector(touchUp) forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:#selector(cancelTimer) forControlEvents:UIControlEventTouchCancel];
and
//if timer fires, this method gets called
-(void) goToNewView {
[self cancelTimer];
[self loadSecondView];
}
// normal button press invalidates the timer, and loads the first view
-(void) touchUp {
[self cancelTimer];
[self loadFirstView];
}
//protected, just in case self.myTimer wasn't assigned
-(void) cancelTimer {
if (self.myTimer != nil)
if ([self.myTimer isValid]) {
[self.myTimer invalidate];
}
}
That should take care of it!
Use a UILongPressGestureRecognizer, added to the button with -addGestureRecognizer:—it'll handle timing the touch and fire an event when it recognizes that the button's been held down for a while. You might want to reconsider your interaction pattern, though—generally, things that can be long-pressed aren't buttons, they're actual pieces of data in a view, like an image or a link in Safari.
One possible approach would be to implement one of the touches events (I don't remember the name, but the method that fires when you touch down on the button), and schedule a timer to fire in three seconds. If the user lifts her finger before that time, cancel the timer and perform the normal button click. If the time does fire (i.e. 3 seconds have elapsed), ignore the touch up event and load your new view.

How to delay while retaining a responsive GUI on Cocoa Touch?

Basically, I have an array of buttons I want to iterate and highlight (among other things) one after another, with a delay in-between. Seems like an easy task, but I can't seem to manage to get it to work cleanly while still being responsive.
I started out with this:
for MyButton *button in buttons {
[button highlight];
[button doStuff];
usleep(800000); // Wait 800 milliseconds.
}
But it is unresponsive, so I tried using the run loop instead.
void delayWithRunLoop(NSTimeInterval interval)
{
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:interval];
[[NSRunLoop currentRunLoop] runUntilDate:date];
}
for MyButton *button in buttons {
[button highlight];
[button doStuff];
delayWithRunLoop(0.8); // Wait 800 milliseconds.
}
However, it is also unresponsive.
Is there any reasonable way to do this? It seems cumbersome to use threads or NSTimers.
NSTimer will be perfect for this task.
The timer's action will fire ever x seconds, where x is what you specify.
The salient point is that this doesn't block the thread it runs on. As Peter said in the comments for this answer, I was incorrect in saying the timer waits on a separate thread. See the link in the comment for details.
Nevermind, Jasarien was right, NSTimer is perfectly suitable.
- (void)tapButtons:(NSArray *)buttons
{
const NSTimeInterval waitInterval = 0.5; // Wait 500 milliseconds between each button.
NSTimeInterval nextInterval = waitInterval;
for (MyButton *button in buttons) {
[NSTimer scheduledTimerWithTimeInterval:nextInterval
target:self
selector:#selector(tapButtonForTimer:)
userInfo:button
repeats:NO];
nextInterval += waitInterval;
}
}
- (void)tapButtonForTimer:(NSTimer *)timer
{
MyButton *button = [timer userInfo];
[button highlight];
[button doStuff];
}