is there a way to pass a boolean to the addClicked method beside using button.tag for the code below?
[cellview.buttonAdd addTarget:self action:#selector(addClicked:) forControlEvents:UIControlEventTouchUpInside];
-(void) addClicked:(id)sender {
}
THanks in advance.
if you want to add a integer property , you can use tag.
if you want to add a nonInteger property , you must use a category with Associative References,the inheritting UIButton can not post property at all.
you can see this :
Subclass UIButton to add a property
Try something like this:
-(void) addClicked:(id)sender
{
UIButton * button = (UIButton*)sender;
NSLog(#"Button Tag: %i", button.tag);
}
Not sure what you mean by pass Boolean.
Short answer: You cannot pass extra information into the method directly.
Why would you want to do that anyway though? What does the button "know" that it would need to communicate, other than the fact that it was clicked?
The way this should be done is via an instance variable in the class that implements the click handler.
If you really must maintain state inside the button itself, subclass it:
#interface CustomButton : UIButton
#property (nonatomic, assign) BOOL myBoolValue;
#end
/* ... */
- (void)addClicked:(id)sender
{
CustomButton *button = (CustomButton *)sender;
if (button.myBoolValue) {
// Whatever you want to do.
}
}
Related
I am very new to iPhone development. I am trying to disable an already existing button but I cant actually obtain a pointer to a specific element in the view. For instance, I have the following in the viewController header
- (IBAction)one:(id)sender;
and the implementation is
- (IBAction)one:(id)sender {
}
which are just event handlers. However, I need disable the button when view opens and I am a little bit lost on how to obtain references to elements outside of the event handler.
So in other words, my thought is to have something like:
UIButton* myButton = //something
where the something is where I am lost on what to do. Any ideas? I greatly appreciate any help I get on here!
You need to create a property for your button in the interface:
#property(nonatomic, retain) IBOutlet UIButton * button;
And add this to implementation:
#synthesize button;
Then connect the button to it in interface builder. After this you can disable the button by:
button.enabled = NO;
Hope I could help!
Just give tag to your button and access your button with tag value.
UIButton *btn = (UIButton*)[self.view viewWithTag:1];
[btn setHidden:YES];
In your .h File
#import <UIKit/UIKit.h>
#interface RpViewController : UIViewController
#property (retain , nonatomic)IBOutlet UIButton *Btn1;
#end
In your .m file , in implementation write this :
#synthesize Btn1;
Now on interface , click on button.
In button's properties - > Drawings - check Hidden checkbox.
Wherever you want to show that button , just write.
[Btn1 setHidden:FALSE];
#property (strong, nonatomic) UIButton *button;
#synthesize button;
// In View Did Load...
self.button = [UIButton buttonWithType:UIButtonTypeCustom]; // button can be of any type.
[self.button setTag:1];
// if you have more buttons initialize it and set its tag. you can get to know which button was pressed using tags.
[button addTarget:self action:#selector(buttonEvent:) forControlEvents:UIControlEventTouchUpInside];
-(void) buttonEvent:(UIButton *) sender
{
NSLog(#"%d",sender.tag);
if(sender.tag == 1)
{
[self.button setEnabled:NO]; // This makes your button disabled, i.e you can see the button but you cannot click on it.
[self.button setHidden:YES]; // This makes your button hidden.
}
}
if you have more doubts ping me back.
I have a view controller class with the following code:
-(void) awakeFromNib{
RootModel *rm = [RootModel sharedModel];
for(NSString *title in rm.rLevels) {
[self addNewButtonWithTitle:title];
}
}
// add a new button with the given title to the bottom of the list
- (void)addNewButtonWithTitle:(NSString *)title
{
// create a new button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
}
the statement
[self addNewButtonWithTitle:title];
generates a warning:
method addNewButtonWithTitle not found.
Con't figure it out.
Thanks
You have 3 options to get rid of the warning:
Declare the method in the #interface block.
If you do not want to expose the method in your interface:
Declare the method in a class extension.
Implement the method above the first call to it.
Have you added method in .h file ?
You need to declare that method in your header file and if not then the method definition should be above the place where you call it.
So in your header file of whereever you have written #interface add the line :
- (void)addNewButtonWithTitle:(NSString *)title
I need to add two additional properties (NSString * and NSMutableArray *) along with three extra methods to UIButton. I also want to reference the new objects using a supertype if that is possible. I do not necessarily want to subclass (as I read that it is tricky and not recommended), but I am quite new to Objective-C and iOS development and don't know what else to do.
I tried to subclass UIButton with my subclass implementing a formal protocol in the following way:
#interface Button : UIButton <MyProtocol> ...
However, I found out this doesn't work like I thought it would, as buttonWithType: returns an object from a subclass. What else can I do to achieve the desired result?
-- EDIT:
Ok, my current code is like this:
#interface Button : UIButton <SteapeObject> {
ActionQueue * actions;
Meta meta;
}
#property (nonatomic, retain) ActionQueue * actions;
#property (nonatomic) Meta meta;
- (id) initWithFrame:(CGRect)frame;
...
And the implementation:
- (id) initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
NSLog (#"finally");
}
return self;
}
An still doesn't work. It seems that when I invoke:
Button * button = [Button buttonWithType: UIButtonTypeRoundedRect];
NSLog (#"%#", [button description]);
I should get two 'finally' strings and two descriptions in the log. However, I only get the two description strings:
[Session started at 2011-02-24 09:47:14 +0100.]
2011-02-24 09:47:15.431 IphoneClient3[702:207] <UIRoundedRectButton: 0x5f47690; frame = (0 0; 0 0); opaque = NO; layer = <CALayer: 0x5f47240>>
2011-02-24 09:47:15.461 IphoneClient3[702:207] <UIRoundedRectButton: 0x6a0f000; frame = (0 0; 0 0); opaque = NO; layer = <CALayer: 0x6a344b0>>
And you can see that the type is still UIRoundedRectButton, but the buttons do not respond to my added methods. Actually, since my overriden initWithFrame doesn't get called, that is to be expected. Perhaps I should default to implementing a custom control...
As far as I know, the doc does not say subclassing of UIButton is not recommended.
I have done it multiple times to add custom properties — without problems.
The only thing to do is to create the button using:
[Button buttonWithType:UIButtonTypeCustom]; // won't work for other button types though
Use a Category.
#interface UIButton (MyButtonCategory)
- (void) myMethod;
#end
#implementation UIButton (MyButtonCategory)
- (void) myMethod
{
NSLog(#"Called myMethod!");
}
#end
[EDIT]
Alternatively, if I finally understand you, you can do this.
#interface MyButton : UIButton
- (id) initWithFrame:(CGRect)rect;
#end
#implementation MyButton
- (id) initWithFrame:(CGRect)rect
{
if ((self = [super initWithFrame:rect])){
// Do your init in here
}
return self;
}
#end
Then calling
MyButton *btn = [MyButton buttonWithType:UIButtonTypeRoundedRect];
Should get you what you want. buttonWithType should call initWithFrame on your subclass.
I found that it is not possible to accomplish that task with the current implementation of the SDK.
Categories might help. Implement like this:
//In the UIButtonMyExtras.h file
#interface UIButton(MyExtras)
//extras
#end
//In the UIButtonMyExtras.m file
#implementation UIButton(MyExtras)
//extra implementation
#end
This adds these extras to every UIButton in your project.
I have multiple UIButtons in my app. I also use interfacebuilder. In my .h i have something like this
IBOutlet UIButton *button1;
IBOutlet UIButton *button2;
IBOutlet UIButton *button3;
- (IBAction)buttonPressed;
Then In my m i want to do something like this
- (IBAction)buttonPressed {
if (theButtonIpressed == button1)
{
// do something if
}
}
The problem is I don't have something called "theButtonIpressed" so I cant do this. What should my if statement look like? I don't want to make a -(IBAction) for each button. Is there something that I can determine which button was pressed? Thanks!
Thanks,
-David
You can also set the tag property for each button in the interface builder and then use it to find out which button was pressed.... This also means that you don't need to define all your button references (UIButton) and keep track of them in code....
- (void) doSomething:(id)sender {
int buttonPressed = [sender tag];
switch (buttonPressed) {
case 0:....
// etc
}
}
Define your - (IBAction)buttonPressed to:
- (IBAction)buttonPressed: (UIButton *) buttonIpressed
Then it will work.
- (IBAction)buttonPressed:(UIButton*)button
But if you're doing something different for each button then the proper way to do it is to create separate IBActions.
You can use tag values for each buttons
IBOutlet UIButton *button1;
button1.tag = 100;
IBOutlet UIButton *button2;
button2.tag = 200;
IBOutlet UIButton *button3;
button3.tag = 300;
- (IBAction)buttonPressed:(id)sender
{
if ([sender tag]==100)
{
NSLOG("button1");
}
else if([sender tag]==200)
{
NSLOG("button2");
}
else {
NSLOG("button3");
}
}
When an IBAction is called:
-(IBAction) onClick1: (id) sender;
What is passed in the sender? Since it's hooked up through the IB, I'm not really sure. My question is how to get the text of the button to be the passed object (NSString most likely) so that I could call it inside the action implementation.
-(IBAction) onClick1: (id) sender {
NSLog(#"User clicked %#", sender);
// Do something here with the variable 'sender'
}
The sender should be the control which initiated the action. However, you should not assume its type and should instead leave it defined as an id. Instead, check for the object's class in the actual method as follows:
- (IBAction)onClick1:(id)sender {
// Make sure it's a UIButton
if (![sender isKindOfClass:[UIButton class]])
return;
NSString *title = [(UIButton *)sender currentTitle];
}
It's actually:
-(IBAction) onClick1: (id) sender {
NSLog(#"User clicked %#", sender);
// Do something here with the variable 'sender'
}
sender is not a NSString, it's of type id. It's just the control that sent the event. So if your method is trigged on a button click, the UIButton object that was clicked will be sent. You can access all of the standard UIButton methods and properties programmatically.
-(IBAction)onClick:(id) sender {
UIButton *btn = (UIButton *)sender;
//now btn is the same object. And to get title directly
NSLog(#"Clicked button: %#",[[btn titleLabel] text]);
}
Simply write the following code
-(IBAction) getButtonTitle:(id)sender
{
UIButton *button = (UIButton *)sender;
NSString *buttonTitle = button.currentTitle;
NSLog(#"Button Title %#",buttonTitle);
}
Thats it... you have done!!!
Sender should be defined as type id, not int or NSString. The sender is the actual object that's calling the method; if you hooked it up to a button, it will be a UIButton, if it's a text field, a UITextField. You can use this to get information from the control (for example the text field's current string value), or compare it to an IBOutlet instance variable if you have multiple controls hooked up to the same action method.
You can just use the following to get the button label and determine which one was clicked:
NSLog(#"Clicked button: %#",[[sender titleLabel] text]);
To answer your question, the id is the object from the IB.
To fetch the text from the button:
NSLog(#"Date::%#",[btn titleForState:UIControlStateNormal]);