How can I disable the touch detection? - iphone

How can I disable the touch detection within the action that running, because I don't want the character flying in the sky like a superman if the player clicking and clicking within the action, the character will never land if they keep clicking.
I found the method "isDone", is that relate to this method??
player click -> action(cannot click within the action) -> action finish -> click again.....
that's what i want~

This is the best answer to your question:
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];

Disable user interactions in your view till the action completes and then enable it again.
To disable touch
[self.view setUserInteractionEnabled:NO];
To enable touch
[self.view setUserInteractionEnabled:YES];
Please try and be a bit more concise of what you want the next time.

Swift 3.0
self.view.isUserInteractionEnabled = false

In Swift 2.2
self.view.userInteractionEnabled = false

Just gonna make a wild assumption that you're talking about the specific Action class in Cocos2D. If that's true, then you should know that every Action has an "isDone" Bool you can check to see if it's done. Let me know if that's what you're asking and I'll post an example, but there's a huge chance you could be talking about something else because your wording is so confusing ;)

You could always put a transparent UIView over top of the area you want to "disable" tap input for, have it listen for taps, and have it ignore them. Remove the UIView (or hide it) when you want input to be listened to again.

Why don't you use some kind of (simple version) boolean to remember i.e. isInAction = true and after the action finished isInAction = false...
So when someone clicks, u use something like
if (!isInAction) {
isInAction=true;
try {
doYourAction;
} catch {
...
} finally {
isInAction=false;
}
}
// The Code is some kind of pseudocode, because I haven't yet programmed for the IPhone, just to visualize what I mean.

Perhaps I didn't understand your question but is this what you're looking for?
- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[Superman Fly];
self.isTouchEnabled = NO;
}
- (void)SupermanLanded{
self.isTouchEnabled = YES;
}

Related

Is MPNowPlayingInfoCenter compatible with AVAudioPlayer?

I start -play with AVAudioPlayer, and then set the nowPlaying dictionary like this:
NSMutableDictionary *songInfo = [[NSMutableDictionary alloc] init];
        
MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage: [UIImage imagedNamed:#"AlbumArt"]];
[songInfo setObject:#"Audio Title" forKey:MPMediaItemPropertyTitle];
[songInfo setObject:#"Audio Author" forKey:MPMediaItemPropertyArtist];
[songInfo setObject:#"Audio Album" forKey:MPMediaItemPropertyAlbumTitle];
[songInfo setObject:albumArt forKey:MPMediaItemPropertyArtwork];
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];
The lock screen always shows a pause button. I receive the remote control events correctly and I can toggle play/pause through the remote control events, but the lock screen keeps showing "pause" even when it is playing.
Now I seen this work with MPMoviePlayerController. Can someone explain how does the MPNowPlayingInfoCenter determine if it should show a play or a pause button?
Have you set the correct AVAudioSessionCategory on the AudioSession? it needs to be AVAudioSessionCategoryPlayback I believe to get it to work.
I'm not using MPNowPlaying at the moment, but apparently I have to, in order to get the audio info displayed on the lock screen.
However, in addition to what #user3061915 said, to manage the play/pause button, I've used UIEventTypeRemoteControl and it works perfect for controlling the play/pause button:
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
//if it is a remote control event handle it correctly
if (event.type == UIEventTypeRemoteControl)
{
if (event.subtype == UIEventSubtypeRemoteControlPlay)
{
[self playAudio];
}
else if (event.subtype == UIEventSubtypeRemoteControlPause)
{
[self pauseAudio];
}
else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause)
{
[self togglePlayPause]; //This method will handle the toggling.
}
}
I just fixed a problem like this in my own app. I originally used [[AVAudioSession sharedInstance] setCategory:withOptions:error:] and supplied AVAudioSessionCategoryOptionMixWithOthers and AVAudioSessionCategoryOptionDuckOthers. This turned out to be my problem. If you set mix with others, you get no remote control events. They still go to the iPod app. If you set duck others, you get remote control events, but it appears as though it causes the problem you describe: the play/pause button shows the wrong thing. I'm not sure why. I got the play/pause button to behave by setting options to 0, or actually just calling setCategory:error:.

How can I stop views on screen from multiplying? (touchesBegan,touchesMoved,touchesEnded)

I am new to Objective C and I am trying to make a basic puzzle game. I am using multiple UIImage objects, some labels and a button. It consists in moving the pieces to its correct position. If the user fails to put a piece in a place, the piece goes back to its original location.
That part works perfectly, the problem begins once I 'remove' that view and continue on the other screens. Whenever I click ANYWHERE on screen the views get multiplied endlessly. Why is that happening?
What should I do?, I am so desperate, I've tried almost everything including ignoring touches, blocking touches, etc. And this only creates more trouble.
I have already tried setting using interactions to no, ignoring interaction events, autoreleasing the view, and I have not reached a solution.
Any help will be very much appreciated. Greetings!
---> I tried posting an image but given that I am a newbie I wasn't able to, however I can send the image to anyone if needed to show you the weird effect I get.
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesCancelled:touches withEvent:event];
}
-(IBAction) navigationConversation: (id)sender{
//[self.view.superview setUserInteractionEnabled:NO];
//[[UIApplication sharedApplication] endIgnoringInteractionEvents];
if (nextButton.hidden == NO) {
conversation *navigationConversationController=[[conversation alloc] initWithNibName:#"conversation" bundle:nil];
[self.view addSubview:navigationConversationController.view];
if (self.view.superview == nil)
[navigationConversationController autorelease];
}
return;
}
Thank God, the problem is solved now. This are the changes I made, and this corrected the mistake. :)
-(IBAction) navigationConversation: (id)sender{
if (nextButton.hidden == NO) {
//I disabled the interactions with the puzzle view in here, thus eliminating the problem
[self.view.superview setUserInteractionEnabled:NO];
conversation *navigationConversationController=[[conversation alloc] initWithNibName:#"conversation" bundle:nil];
[self.view addSubview:navigationConversationController.view];
if (self.view.superview == nil)
[navigationConversationController autorelease];
}
return;
}
Thanks to everyone who looked! and wanted to help! I hope this works for other people having the same issues.

Double blow detection in iPhone

I have seen many tutorials over internet to detect blow in iPhone but my app's requirement is that I need to detect single blow and double blow both so that if user blow single time it can perform action a and if the user blow two times together then to perform action b.
Any way to do this?
Thanks all,
Surely if you know how to detect a single blow, you could just have a timer with a threshold & see if another blow happens within that time? Something like -
-(void)userDidBlow {
if (hasBlownOnce) {
hasBlownOnce = NO;
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(singleBlowTimedOut) object:nil];
// do double-blow stuff
} else {
hasBlownOnce = YES;
[self performSelector:#selector(singleBlowTimedOut) withObject:nil afterDelay:kDoubleBlowTime];
}
}
-(void)singleBlowTimedOut {
hasBlownOnce = NO;
// do single-blow stuff
}
I haven't tested it, but it looks ok :)

Detect when GameCenter UI is displayed

I'm trying to integrate my game with Game Center and encountered this problem:
When user is authenticated for a first time, Game Center shows its UI for setting up the profile.
My problem is that I can not detect when this windows is shown - I want to pause my game at that moment and not play any sounds.
viewWillDisapper, viewDidDisapper in UIViewController are not called, neither are any of AppDelegate methods are called at this time.
I think I know how detect alert views (using changing key window notification), but that Account windows still is not detected there.
Is there any way to do this?
Building on executor21's answer here, I put this together which seems to do the trick in early testing. You can probably adapt it into something less fragile. It is built on the premise that the Game Center notification gets its own window, and it has exactly one subview of type GKGameEventView:
+(BOOL)isGameCenterNotificationUp
{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *win in windows)
{
NSArray *winSubViews = [win subviews];
if([winSubViews count] == 1)
{
Class gcNotificationClass = NSClassFromString(#"GKGameEventView");
if(gcNotificationClass && ([[winSubViews objectAtIndex:0] isKindOfClass:gcNotificationClass]))
{
return YES;
}
}
}
return NO;
}

Disabling user interaction on CCSprite or CCScene in cocos2d for Iphone

I am developing a game on Iphone using cocos2d. I have a CClayer containing 20 CCSprite. I am playing a sound and I would like to disable the touch events on all the CCSprite or on the entire layer while the sound is playing. I looked at the property of CCLayer called isTouchEnabled but the behavior doesn't propagate to the children (all the CCSprite). Unless it is not documented, there seems to be no equivalent property for CCsprite. Does anybody know an easy way to this?
Thanks
I ma using below method to disable touch on CCMenu items on a layer below on a view may be help you out.
Call the below method and disable all sub Menu or subNode.
[self MenuStatus:NO Node:self]; // to disable
method is:
-(void)MenuStatus:(BOOL)_enable Node:(id)_node
{
for (id result in ((CCNode *)_node).children)
{
if ([result isKindOfClass:[CCMenu class]])
{
for (id result1 in ((CCMenu *)result).children)
{
if ([result1 isKindOfClass:[CCMenuItem class]])
{
((CCMenuItem *)result1).isEnabled = _enable;
}
}
}
else
[self MenuStatus:_enable Node:result];
}
}
[self MenuStatus:YES Node:self]; // to enable**
A member of another forum posted this solution
So all your sprites normally receive touch events? If you know when the sound is playing, you just could have them check that and ignore the touch if the sound is playing. For example, if your sprites implement the CCTargetedTouchDelegate protocol, you could do something like:
- (BOOL)ccTouchBegan:(UITouch*)touch withEvent:(UIEvent*)event {
if (soundIsPlaying) {
return NO; // i.e., the sprite is currently uninterested in the touch
}
// Other checks and behaviour here.
return YES;
}