cocos2d custom dialog box with yes/no choices - iphone

As of now, I can only do:
`UIAlertView* dialog = [[UIAlertView alloc] init];
[dialog setDelegate:self];
[dialog setTitle:#"New Game"];
[dialog setMessage:#"Are you sure you want to start a new game? This will overwrite your current game."];
[dialog addButtonWithTitle:#"Yes"];
[dialog addButtonWithTitle:#"No"];
[dialog show];
[dialog release];
...
- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex==0) {
gametype = 1;
[[CCDirector sharedDirector] replaceScene:[CCTransitionCrossFade transitionWithDuration:1 scene:[GameScene node]]];
}
}
`
The bad thing is that the dialog box really does not mix in with the whole theme of the application.
Is there a way I can customize or create a dialogue box that appears?
I've heard that customizing UIAlertView has been very controversial to the point of being rejected form the app store. I don't think I should go with this method. Do you have any suggestions/code I can use?
PS: I have a dialogue box image and yes/no buttons already done.

If you already have a dialog box and YES/NO buttons, then I would just add the dialog box the the layer a sprite with the YES/NO buttons overlaid as CCMenuItemImage(s). Then you can have the no button just hide the visibility of the menu and the dialog box and the yes button replace the scene.
dialogBox = [CCSprite spriteWithFile:#"dialogBox.png"];
CCMenuItemImage *yesButton = [CCMenuItemImage itemFromNormalImage:#"yes.png" selectedImage:#"yes.png" target:self selector:#selector(yesSelector)]
CCMenuItemImage *noButton = [CCMenuItemImage itemFromNormalImage:#"no.png" selectedImage:#"no.png" target:self selector:#selector(noSelector)]
Then in your noSelector method you can just hide the dialog box and in your yesSelector just replace the scene.

Related

LongPress on iPhone app opens 3 Alerts? AlertView or Gesture Code Issue [duplicate]

I created an application. Through developing it, i used long press button to show an alert.
This is my code:
- (IBAction)longPressDetected1:(UIGestureRecognizer *)sender {
// label1.text = #"Select Iran to observe its historical data projections ";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"Press the blue button (+) to select your region "
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
}
Question: When I want to cancel the UIAlertView by using the cancelIbutton, I must press this button three times to cancel the UIAlertView. it means UIAlterview cannot be canceled just by one press.
Could you please help me?
The problem is that your are showing more than one alert view. Your long press handler will get called for different states.
From the docs for UILongPressGestureRecognizer:
Long-press gestures are continuous. The gesture begins (UIGestureRecognizerStateBegan) when the number of allowable fingers (numberOfTouchesRequired) have been pressed for the specified period (minimumPressDuration) and the touches do not move beyond the allowable range of movement (allowableMovement). The gesture recognizer transitions to the Change state whenever a finger moves, and it ends (UIGestureRecognizerStateEnded) when any of the fingers are lifted.
So you end up displaying an alert for the "Began" state, then the "Changed" state, and again for the "Ended" state. If you moved your finger around you would get a stream of "Changed" states and you would end up showing an alert for every one of them too.
You need to decide when you actually want the alert to appear. Do you want it to appear at the first "Changed" state or when the user lifts their finger and you get the "Ended" state.
Your code needs to be something like this:
- (IBAction)longPressDetected1:(UIGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
// label1.text = #"Select Iran to observe its historical data projections ";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"Press the blue button (+) to select your region "
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
}
}
This will show the alert when the user lifts their finger. Change UIGestureRecognizerStateEnded to UIGestureRecognizerStateChanged if you want the alert to appear as soon as the long press is recognized. But keep in mind you may still get multiples since a long press can generate multiple "Changed" states. In this case you need to add an additional check to only show the alert if there isn't already one.
Actually, here's an easy way to support a single alert on the "Changed" state:
- (IBAction)longPressDetected1:(UIGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateChanged) {
sender.enabled = NO; // Prevent any more state updates so you only get this one
sender.enabled = YES; // reenable the gesture recognizer for the next long press
// label1.text = #"Select Iran to observe its historical data projections ";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"Press the blue button (+) to select your region "
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
}
}
Try this
- (IBAction)longPressDetected1:(UIGestureRecognizer *)sender {
// label1.text = #"Select Iran to observe its historical data projections ";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"Press the blue button (+) to select your region "
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
alert.tag =10;
[alert show];
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
switch (alertView.tag)
{
case 10:
if (buttonIndex==0)
{
}
break;
}
}
This is an old question, but I had a similar issue.
Any UILongPressGestureRecognizer will generate at least 4 changes of state:
changed - (i.e. changed to started)
began - (i.e. started)
changed - (i.e. changed to ended)
ended - (i.e. ended)
So to handle it well, you need to choose which of those conditions will activate an action.
The simplest, which sort of corresponds to 'touch up inside' for a UIButton is to detect the 'ended' state.
An example is below where 'longPress' is the instance of UILongPressGestureRecognizer
- (void)longPressedLastImage:(UILongPressGestureRecognizer*) longPress {
if (longPress.state == UIGestureRecognizerStateEnded) {
// do what you would in response to an equivalent button press
}
}
This lets you treat the continuous press more like the basic UIButton action.
'simple is better than complex' - T Peters - the Zen of Python

how do I add a menu to an already-made game in cocos2d and box2d for iphone?

I have an existing game that I want to have a title screen with a button "play" to the app that loads the game.
EDIT: The interface was made in Level Helper
Here's how you can implement a menu that changes scenes with a transition. In your HelloWorldLayer.m file, add this:
-(id) init
{
if( (self=[super init])) {
CCMenuItemImage *menuImage = [CCMenuItemImage itemFromNormalImage:#"yourimage.png" selectedImage:#"Icon.png" target:self selector:#selector(changeScene:)];
CCMenu *menu;
menu = [CCMenu menuWithItems:menuImage, nil];
[self addChild:menu];
}
return self;
}
-(void) changeScene:(id)sender
{
[[CCDirector sharedDirector] replaceScene:[CCTransitionZoomFlipX transitionWithDuration:1 scene:[Scene1 node]]];
}
This creates a menu item image assigned to a selector, adds it to a menu, and then on click, transitions to a new scene, which I will show you how to do now. Create a new class called Scene1, and just to show that the transition worked, we will add a sprite in this new scene. In your init method:
-(id) init
{
if( (self=[super init])) {
sprite = [CCSprite spriteWithFile:#"yourimage.png"];
sprite.position = ccp(100,200);
[self addChild:sprite];
}
return self;
}
If you see this new sprite on the screen, it means that everything worked.
I'll assume by saying u have an existing game, that u have the source code of the game.
All u need is to make a new CCLayer with a CCMenu (containing the CCMenuButton u want) that all it does is load the CCLayer that loads as u start the game, and make ur CCLayer the one that gets loaded as u start the app.
create a menu using the following code:
// Intalize your menu item
CCMenuItem *menuItem = [CCMenuItemFont itemFromString:#"This is what you want your item to say" target:self selector:#selector(selectorToHandleYourSelection)];
// Define where you want your item to be
menuItem.position = ccp(100,100);
// Intalize a menu for your menu item
CCMenu *menu = [CCMenu menuWithItems:menuItem, nil];
// Add the 'menu' as a child to your layer
[self addChild:menu];
// If the item position isn't defined then you can align the items horizontally
[menu alignItemsHorizontally];

Custom UIalertView in iOS5

Do anywho know a custom UIAlertView class what is working in iOS5 ?
I'm looking for a class like TSAlertView, with that I will able to put 2 buttons stacked into alert.
( http://cocoacontrols.com/platforms/ios/controls/tsalertview )
Thanx for help.
UIAlertView in iOS 5 has UIAlertViewStyles
UIAlertViewStyleDefault
UIAlertViewStyleSecureTextInput
UIAlertViewStylePlainTextInput
UIAlertViewStyleLoginAndPasswordInput
EDIT Sorry for misunderstanding your problem. The alert view shown in the linked page is extremely easy to reproduce. Here's what I came up with:
I implemented this with a category for convenience but you could easily just implement it elsewhere. Basically what you do is add a cancel button and then hide it. That way there are three buttons as far as the alert view is concerned and it does not place the two visible buttons side by side. The category implementation is as follows:
-(void)showWithCutCancelButton{
// Make sure alert view will look right
if (self.cancelButtonIndex == -1 || self.numberOfButtons < 3) return;
self.clipsToBounds = YES; // or else cancel button will still be visible
[self show];
// Shrink height to leave cancel button outside
self.bounds = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height - 64);
}
Then you show this by calling:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hello" message:#"Message here" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Option1", #"Option2", nil];
[alert showWithCutCancelButton];

UIActionSheet long list behavior changed in 4.2?

I am seeing some changed behavior in iOS 4.2 with UIActionSheet. I can't find anything in Apple's developer docs or forums about it, so I'm not sure how to resolve it.
In my list app, I present the user with an actionsheet from which she can pick the list she wants to load on startup. Obviously that means there will be a variable number of items, and the control handles it fine. Until about 7 items, it shows all items as buttons. Once it crosses that threshold, it puts the items into a scroll view to choose from. Until 4.2, it included the Cancel button in that scrolling list. In 4.2, it now seems to be separating the Cancel control, leaving it as a button while putting the rest of the items into the scroll view. The problem is that it appears that it keeps the Cancel item in the list of button indices, so that when I inspect the buttonTitleAtIndex:buttonIndex in either clickedButtonAtIndex: or didDismissWithButtonIndex:, the first item returns "Cancel", then the other item titles are off by 1. Clicking the Cancel button also returns "Cancel".
Anyone else experienced this and have a suggestion for how to handle it? Again, this worked fine in 3.0, 3.1, 4.0, and 4.1.
Here's the relevant code I'm using:
- (IBAction)popupDefaultListActionSheet {
UIActionSheet *popup = [[UIActionSheet alloc]
initWithTitle:nil
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (List *l in allActiveLists) { // allActiveLists defined elsewhere
[popup addButtonWithTitle:[l label]];
}
popup.actionSheetStyle = UIActionSheetStyleBlackOpaque;
popup.tag = 23;
[popup becomeFirstResponder];
[popup showInView:[self.view.window.subviews objectAtIndex:0]];
[popup release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
DLOG(#"AppSettingsVC.actionSheet didDismissWithButtonIndex: %d", buttonIndex);
NSString *defaultListName = [actionSheet buttonTitleAtIndex:buttonIndex];
DLOG(#"chosen default list was: %#", defaultListName);
}
Try adding the cancel button dynamically at the end instead of setting it up initially:
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"My Action Sheet"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (I32 i = 0; i < itemCount; i++) {
[actionSheet addButtonWithTitle:itemText];
}
[actionSheet addButtonWithTitle:#"Cancel"];
[actionSheet setCancelButtonIndex:itemCount];
Seems to work correctly in iOS 4.2 for us at least.

Which button was tapped in alert view

I create alert view like this:
UIAlertView* av = [UIAlertView new];
av.title = #"Dealer offer Insurence";
[av addButtonWithTitle:#"YES"];
[av addButtonWithTitle:#"NO"];
How can I find out which button was tapped by user?
In what way does the documentation fall short? You could even copy code from one of the many code samples.