CCMenuItemImage change runtime cocos2d - ios5

I have created a menuitem using
menuItemImage=[CCMenuItemImage itemFromNormalImage:#"image_old.png" selectedImage:#"image_old.png" target:self selector:#selector(play)];
I am using below code to change the CCMenuItemImage but it isn't working. It say's incompatible pointer type sending 'CCTextured2D' to parameter of normalimage.
[menuItemImage setNormalImage:[[CCTextureCache sharedTextureCache]addImage:#"image_new.png"]];
How to change menuItemImage runtime?

You can change the normalImage with the following code. I know this is not good practice but temporarily it works fine.
[menuItemImage setNormalImage:[CCSprite spriteWithFile:#"image_new.png"]];
I Hope it would work for you.

The solution for this problem is to make an extra menu item with nearly the same name
Change the state of the menuItems by swapping the visible property from false to true and vice versa
Example:
CCMenuItem *menuItemOn;
CCMenuItem *menuItemOff;
-(void)ChangeMenuItem{
menuItemOff = [CCMenuItemImage itemWithNormalImage:#"buttonOff.png" selectedImage: #"buttonOff.png" target:self selector:#selector(Method_off)];
itemJoinOff = [CCMenuItemImage itemWithNormalImage:#"buttonOn.png.png" selectedImage: #"buttonOn.png" target:self selector:#selector(Method_On)];
menuItemOff.visible = false;
menuITemOn.visible = true;
menuItemOff position ..... etc
}
Whenever the menu On/Off state must change, make MenuItemOn visible and menuItemOff unvisible.

Related

Can I pass a UIButton in scheduledTimerWithTimeInterval?

I need to disable a button for 2.56 seconds, long after control is returned to the user. I am using the following code where theButton is type UIButton, defined at the beginning of the routine with
UIButton *theButton = sender;
and later calling the following which will update a label and then, hopefully, enable the button. Updating the label works perfectly but it crashes when trying to enable the button so I must be passing the UIButton incorrectly. Can anyone give me an example / correct me on this?
[NSTimer scheduledTimerWithTimeInterval:2.56
target:self
selector:#selector(updateLabel:)
userInfo:theButton
repeats:NO];
Thanks for your help...
I hope you are writing updateLabel: method as follows
-(void) updateLabel:(NSTimer *)timer1
{
//your other code...
[(UIButton *)[timer1 userInfo] setEnabled:YES];
//your other code
}
Thanks,

How to get keyboard with Next, Previous and Done Button?

I want to have a keyboard which has a Next,Previous and Done button on top of it.
I have seen that in many apps.
Especially where there are forms to be filled.
I want to achieve something similar to above keyboard
How can I get that?
You'll find the answer on this other post.
I checked the iOS Library and the inputAccessoryView of a UITextField is exactly what you're looking for !
Hope this helps !
I just created a class called BSKeyboardControls which makes it very easy to add the controls to a keyboard. The class, instructions and example code can be found here at GitHub.
The controls works for text fields and text views and are optimized for both iPhone and iPad.
-(BOOL)textFieldShouldBeginEditing: (UITextField *)textField
{
UIToolbar * keyboardToolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
keyboardToolBar.barStyle = UIBarStyleDefault;
[keyboardToolBar setItems: [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithTitle:#"Previous" style:UIBarButtonItemStyleBordered target:self action:#selector(previousTextField)],
[[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStyleBordered target:self action:#selector(nextTextField)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(resignKeyboard)],
nil]];
textField.inputAccessoryView = keyboardToolBar;
}
- (void)nextTextField {
if (textField1) {
[textField1 resignFirstResponder];
[textField2 becomeFirstResponder];
}
}
-(void)previousTextField
{
if (textField2) {
[textField2 resignFirstResponder];
[textField1 becomeFirstResponder];
}
}
-(void)resignKeyboard {
[textField1 resignFirstResponder];
[textField2 resignFirstResponder];
}
I have a utility class that basically does this for you.
https://github.com/kalvish21/CustomKeyboard
The idea is very simple. You have to add an accessory tool bar with bar button items on it. There's a delegate which defines where what that button will do.
https://github.com/hackiftekhar/IQKeyboardManager
This is the best keyboard handler I have seen so far. Very excellent way to manage Text inputs.
Some of its features
1) ZERO LINE OF CODE
2) Works Automatically
3) No More UIScrollView
4) No More Subclasses
5) No More Manual Work
6) No More #imports
This is a custom control which is placed directly above the keyboard. I think a UIToolbar can be used for that.
Previous and next passes around the firstResponder of the textFields and Done will do the resign as well as hide the toolbar.
To match the keyboard animation have a look at this code I found or at SO: "What is the iPhone's default keyboard animation rate?"
I have created a repository with an implementation of this feature that works on iPhone/iPad in all orientations and highly customizable.
As mentioned in other answers, it's the inputAccessoryView that you're looking for.
I would like to add an alternative way here, by using this cocoapods:
pod 'UITextField-Navigation'
All UITextFields will have two additional properties: nextTextField and previousTextField. You can then simply connect the nextTextField in the Interface Builder and the Previous, Next and Done buttons are added automatically for you, all functional, no more code is needed, no subclassing.
You can also customize the UI, add more buttons, etc as you want to.

Objective-C: Passing a selector to an object

I'm implementing a button class in cocos2d, and I want to be able to pass the selector when the button is created. Here is Button.m:
#import "CCButton.h"
#implementation CCButton
+(CCButton*) buttonFromImage:(NSString*)image selectedImage:(NSString*)selectedImage atPosition:(CGPoint)position selector:(SEL)selector_method
{
CCMenuItem *menuitem = [CCMenuItemImage itemFromNormalImage:image selectedImage:selectedImage target:self selector:selector_method];
menuitem.position = position;
CCButton *menu = [CCMenu menuWithItems:menuitem, nil];
menu.position = CGPointZero;
return menu;
}
#end
It inherits from CCMenu. What I want to do is define the selector method wherever create my button. For example, if I have a menu, I want the selector to be in the menu, and assign the selector to the button (in menu.m):
backButton = [CCButton buttonFromImage:#"image1.png" selectedImage:#"image2.png" atPosition:ccp(120,70) selector:#selector(backTouched:)];
[self addChild:backButton z:1];
...
- (void)backTouched:(id)sender {
//do what i want the button to do here
}
This crashes when I touch the button. How do I implement what I want?
Thanks for the help,
Dave
Edit: the error I get is bad pointer, SIGABRT
The target cannot be self. The target has to be the class that implements the button you have created.
When passing in the selector as you create the button, also pass in the target of the button creating class.
In other words, target is the class that contains the method that you pass as the selector.
Hope that made things clear :)
PS: Here's what you should try. Note that your buttonFromImage now takes in a target attribute which is set when you create the backbutton. Also the target that you set in your buttonFromImage is not self, but the target that comes in from the buttonFromImage method.
#implementation CCButton
+(CCButton*) buttonFromImage:(NSString*)image selectedImage:(NSString*)selectedImage atPosition:(CGPoint)position selector:(SEL)selector_method target: (id)target
{
CCMenuItem *menuitem = [CCMenuItemImage itemFromNormalImage:image selectedImage:selectedImage target:target selector:selector_method];
menuitem.position = position;
CCButton *menu = [CCMenu menuWithItems:menuitem, nil];
menu.position = CGPointZero;
return menu;
}
#end
//*************************************************
backButton = [CCButton buttonFromImage:#"image1.png" selectedImage:#"image2.png" atPosition:ccp(120,70) selector:#selector(backTouched:) target:self];
[self addChild:backButton z:1];
//...
- (void)backTouched:(id)sender
{
//do what i want the button to do here
}
There are a couple of things that could be the problem, but none of them have anything to do with passing a selector:
You're passing self (which in a class method is the CCButton class) as the target of the button, but CCButton does not have a corresponding class method, and it's almost certainly not the object that you intend to respond to the action.
Your method says it returns a CCButton, but you're actually returning a CCMenu. Unless CCButton and CCMenu are structurally identical (i.e. CCButton has no instance variables), this is almost guaranteed to cause a crash, and is wrong in any case.

How to programmatically replace UIToolBar items built in IB

I have a toolbar with various image buttons, created in Interface Builder.
I'd like to be able to programmatically replace one of the buttons with an activity indicator when pressed, and then put back the original button but change its color from white to yellow when the activity completes.
Is this possible with an IB built toolbar or must I look at building the whole toolbar programmatically and custom views?
Here is an example of what I did in a similar situation. I wanted to build the toolbar using Interface Builder but toggle one of the BarButtonItems based on whether or not it was "checked". In this example, there are a few key things to note. The following 2 member variables are defined for the class in the header file:
NSMutableArray *toolbarItems;
IBOutlet UIToolbar *toolbar;
NSUInteger checkUncheckIndex;
When I want to update the checked status, I call this function... Please note that there is a selector defined called checkUncheckClicked that is called when the particular button in the UIToolbar is clicked. And the UIToolbar is set up as an IBOutlet to toolbar. Alternately, you could hook up the UIBarButtonItem as an outlet itself and use that as your logic to identify the index of the button, or for that matter, you could hard-code the index of the button if things won't change over time. Finally, there is a checked.png and unchecked.png to alternate between that is included in the project.
- (void)updateBarButtonItemChecked:(BOOL)checked {
if (toolbarItems == nil) {
toolbarItems = [[NSMutableArray arrayWithArray:toolbar.items] retain];
checkUncheckIndex = -1;
for (NSUInteger i = 0; i < [toolbarItems count]; i++) {
UIBarButtonItem *barButtonItem = [toolbarItems objectAtIndex:i];
if (barButtonItem.action == #selector(checkUncheckClicked)) {
favoriteIndex = i;
break;
}
}
}
if (checkUncheckIndex != -1) {
UIBarButtonItem *barButtonItem = [[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:checked ? #"checked.png" : #"unchecked.png"]
style:UIBarButtonItemStylePlain target:self action:#selector(checkUncheckClicked)] autorelease];
[toolbarItems replaceObjectAtIndex:checkUncheckIndex withObject:barButtonItem];
toolbar.items = toolbarItems;
}
}
And, of course toolbarItems and toolbar should be released in your dealloc for the class.
Hope this helps!
Here is the approach I used
It seemed to be much simpler to manage the toolbar entirely programatically so ....
In your view controller declare 1 or more sets of UIBarButtonItem items as property items also declare and hookup the toolbar as a UIToolbar property. Also declare 1 or more arrays to hold the items.
In the implementation
In viewDidLoad alloc and set your UIBarButtonItems for example
playButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemPlay
target:self
action:#selector(handlePlayClick)];
Flexible buttons (for alignment etc) are declared like this
flexButton1 =[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil action:nil];
There are several initMethods to handle the different types of buttons toolbars support. All follow a syntax similar to the above. Worth noting is the target and action settings. Target: would normally be self, action is the name of the function that button should trigger.
After alloc'ng your UIBarButtons add them to an array using initWithObjects.
Then to assign the buttons to the toolbar you would call
[toolbar setItems:<array name>];
Dont forget to dealloc your UIBarButtons and arrays at the end of your code.
Hope this helps. If you need more code let me know.
Rich D.
Swift
Much has changed since these answers have been posted. Here is a Swift 2.0 solution.
It matters not how the original UIBarButtonItem you are replacing has been created programmatically. All you need is the UIToolbar outlet. To replace, say, the 2nd item from the left, do this:
var toolbarItems = self.toolbar.items
let newItem = UIBarButtonItem(barButtonSystemItem: .Play, target: self, action: "play")
toolbarItems![1] = newItem
self.toolbar.setItems(toolbarItems, animated: true)
Swift has a much easier way. In my case, I am switching the play button with the pause button every touch.
#IBAction func playandPause(sender: UIBarButtonItem) { // Here we are creating an outlet. Hook this up to the bar button item.
for (index, button) in toolbarItems!.enumerate() { // Enumerating through all the buttons
if button === sender { // === operator is used to check if the two objects are the exact same instance in memory.
var barButtonItem: UIBarButtonItem!
if mediaplayer.playing {
mediaplayer.pause()
barButtonItem = UIBarButtonItem.init(barButtonSystemItem: .Play, target: self, action: #selector(playandPause(_:)))
}else {
mediaplayer.play()
barButtonItem = UIBarButtonItem.init(barButtonSystemItem: .Pause, target: self, action: #selector(playandPause(_:)))
}
toolbarItems![index] = barButtonItem // Replace the old item with the new item.
break // Break once we have found the button as it is unnecessary to complete the rest of the loop
}
}
}
I think it should be possible. You might either try creating an IBOutlet for that specific button in your ViewController class, and connect the button from IB to that outlet, or you can use the items property of that UIToolbar instance (you do have a reference to that, don't you?) and find the appropriate item in there, create a new NSArray with modified items, and set it back on that toolbar.items property.
HTH
A note on this - the toolbar will strip out any color in your icons, so you still won't be able to make it yellow. You'll need to change the image shape to indicate "on" instead.
Alternatively you'll need to load your BarButtonItems with UIButtons (use the initWithCustomView) and set the image of the button appropriately.
HTH
Try:
- (void)setTitle:(NSString *)title forItem:(int)item ofToolbar:(UIToolbar *)tb {
NSMutableArray *newItems = [tb.items mutableCopy];
UIBarButtonItem *old = [newItems objectAtIndex:1],
*titled = [[UIBarButtonItem alloc] initWithTitle:title style:old.style target:old.target action:old.action];
[newItems replaceObjectAtIndex:1 withObject:titled];
tb.items = newItems;
[titled release];
}
For the entire toolbar that you created in IB (that is to say, not the individual toolbar items), create an IBOutlet:
#IBOutlet weak var toolbarThatYouMade: UIToolbar!
This is an array of individual toolbar items, so you would access the leftmost member (for example) with a [0] index:
toolbarThatYouMade.items![0].image = UIImage(named: "New Image")
This code assumes that you have an image named "New Image" in your assets.
You can then trigger an image change for a toolbar item without having to access that specific item itself; for example, if you were using this for something like a media player, you could toggle pause/play images from:
a) the Pause/Play button itself,
b) the Stop button,
c) when you are notified of a change of player state,
or
d) something else entirely. (Be brave! Be bold! Be something else that begins with 'b'!)

How do I change the color of a Cocos2d MenuItem?

[MenuItemFont setFontSize:20];
[MenuItemFont setFontName:#"Helvetica"];
//I'm trying to change the color of start (below item)
MenuItem *start = [MenuItemFont itemFromString:#"Start Game"
target:self
selector:#selector(startGame:)];
MenuItem *help = [MenuItemFont itemFromString:#"Help"
target:self
selector:#selector(help:)];
Menu *startMenu = [Menu menuWithItems:start, help, nil];
[startMenu alignItemsVertically];
[self add:startMenu];
MenuItemFont *start = [MenuItemFont itemFromString:#"Start Game"
target:self
selector:#selector(startGame:)];
[start.label setRGB:0 :0 :0]; // Black menu item
Label is a property of MenuItemFont, a subclass of MenuItem, so you lose it during the implicit cast to MenuItem.
Alternatively, you could do:
[((MenuItemFont *)start).label setRGB:0 :0 :0]
(but that's ugly, and startMenu will take a MenuItemFont with no complaints).
Keep in mind that the colors are for the most part hardcoded in MenuItemFont, so calling 'setIsEnabled' will set the colors back to grey or white. This happens around line 239 of MenuItem.m if you need to tweak it. If I get around to making a patch to expose this functionality on MenuItemFont (assuming it's not already in the pre-.7.1 sources) I'll update my post.
setRGB has been set to setColor in newer versions. For example:
[start.label setColor: ccc3(200,0,200)];
You can change it like this (at least on Cocos2d version 0.99.5)
CCMenuItemFont *startMenuItem = [CCMenuItemFont itemFromString:#"Start" target:self selector:#selector(startTapped:)];
[startMenuItem setColor:ccBLACK];