I have a view controller let's call it "View Controller A".
I have a different class(derived from NSObject and in .h and .m pair), let's call this class "B".
From a function of "B" I am adding a button in "A" using addSubView.
The button is getting added but now I want to attach an event to this newly button.
I am using
[newButton addTarget:self etc. etc.]
but it isn't working.
I don't want to declare the event in View Controller "A".
Is there any way to get rid of this?
Thanks all for reading this..
[newButton addTarget:viewControllerA etc. etc.]
EDIT: More complete version:
[newButton addTarget:viewControllerA action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
This assumes that class B has a reference to View Controller A named viewControllerA. It also assumes that View Controller A has implemented the method:
- (void)buttonAction:(id)sender;
EDIT 2: So this is what you want:
[newButton addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
I assume you already have that and I assume that the reason it doesn't work is because you have a method that looks something like this:
+ (void)addButtonToController:(UIViewController *)controller;
That's a class method. There is no self in a class method. One possible solution is to make it a singleton class and simply change the method to:
- (void)addButtonToController:(UIViewController *)controller;
You would call that method using:
[[ClassB sharedInstance] addButtonToController:controller];
If you don't know how to create a singleton class I could update my answer a third time to include that. :)
EDIT 3: I still think my original answer is the correct one. You don't have to implement - (void)buttonAction:(id)sender; in every controller. You could use inheritance or a category, to have access to this method in every controller without having to implement it for every controller. If you need help with this let me know.
Related
I need several UIButtons to all connect to the same IBAction so the buttons can all do the same thing without having to copy and paste the code. Please tell me if there is a way to do this! It might be right under my nose, but I can't find it. Thanks!
Simply add the same target and selector to each button:
[button1 addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
[button2 addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
// etc.
For this You need to use set IBOutlet for Each Button or Set tag for each button if you are using Outlet then used this code .h
#interface RootViewController_Phone : UIViewController
{
IBOutlet UIButton *btn1;
IBOutlet UIButton *btn2;
}
- (IBAction)buttonPressed:(id)sender;
-(void)CallButtonsMethod;
#end
Now in .m file
- (IBAction)buttonPressed:(id)sender{
if([sender isEqual:btn1])
{
[self CallButtonsMethod];
}
if([sender isEqual:btn2])
{
[self CallButtonsMethod];
}
}
-(void)CallButtonsMethod
{
//your Code
}
Use IBOutletCollections.
Here is tutorial for that:
http://useyourloaf.com/blog/2011/03/28/interface-builder-outlet-collections.html
I've found that I'm usually not able to hook up multiple buttons (or even a single button, for that matter) in IB to an already existing IBAction in code, by Ctrl-dragging from the button to the IBAction in the m file. Xcode tries to create a new action in the dragged-to file, but won't connect to an existing action. [This is true for Xcode 4.6.1 and several previous (maybe all) versions.]
The approach in the accepted answer in the following link works if the IBAction is in the view controller which is the "File Owner" for the view containing the button:
Connect object in .xib to existing IBAction
However if you want your IBAction to be in the view's own class, rather than the view controller's class, then the following approach works:
Drag only one button onto the canvas in IB first. Control-drag from
the button to the view's .m file.
Drop the dragged line in any vacant space in the implementation section of the code.
Define a new IBAction in the little popup dialogue box. So now you have one
button hooked up to an IBAction.
Now instead of dragging more buttons from the object library, hold
down the Option key and drag out a new button from the original one.
This new button will come hooked up to the same IBActions as the
original one. (If you need to create lots and lots of buttons and
this seems tedious, you can select a bunch of already created ones simultaneously and
Option-drag to create as many more in a single go.)
i think the title is self explaining.
I have an UIPopOverController, in it is a tableview and when i select a cell, i want to tell it the UIViewController.
Is there an easy solution or do i need KeyValueObserving or notifications?
Post an NSNotification from the tableview and add the UIViewController as an observer.
you could move with one of two approaches as per your choice.
first : using delegate/protocol.
http://www.thepensiveprogrammer.com/2010/05/objective-c-protocols-and-delegates.html
second: Set your UIViewController as the target for your UIButton.
for example
[btn addTarget:myController action:#selector(ActionWillBePerformedInController:) forControlEvents:UIControlEventTouchUpInside];
Posting an NSNotification will work well... you can also create a callback object and selector in your UITableViewController class.
you could initialize your UITableViewController with a callback object and callback selector
initWithTarget:(id)theTarget andSelector:(SEL) theSelector
...save off the values to properties
then from the didSelectRowAtIndexPath in your tableView... call
[self.target performSelector:self.selector];
using this methodology, you can define your own callback methods as you wish.. from your ViewController class that created the popover, you could do something like this...
[[MyTableView alloc] initWithTarget:(self) andSelector:#selector(popoverControllerDidRequestClose)];
I've created a custom UIView class FormDropdown, which contains a question & button in the nib. In the class is also an NSArray property which is supposed to store the various options for the button.
So a button can be placed by doing this, in for instance a viewDidLoad method:
FormDropdown *dropdown = [FormDropdown dropdownWithQuestion:#"This is an example question" andLabel:#"Select one" andOptions:[NSArray arrayWithObjects:#"One", #"Two", #"Three", nil]];
[self.view addSubview:dropdown];
Obviously, I'd like the button to, when tapped, bring up a UIPickerView with the options showing. But I'm stuck on how to send the options to any method. I know I can attach an action to the button like so:
[dropdown.dropdownButton addTarget:self action:#selector(dropdownPressed:) forControlEvents:UIControlEventTouchUpInside];
..but I can't see how I would pass the options from the dropdown.options array to the method?
I believe that you can do this by adding an "associative reference" from the UIButton to your object data.
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocAssociativeReferences.html
I am looking for a way to do that as well... however, it doesn't seem possible.
My possible solution: I think I am going to create a subclass of UIButton, and add a "NSObject *tagObject" property to it.
Anyone seems something wrong about it? (I am using ARC, and I am wondering if that would cause objects to remain in memory - I do not think so).
in xxx.h
UIButton *b1, *b2, *b3;
in xxx.m
b1 = ---- similarly for b2 and b3
Now I want that on Click event I store the title in the string. How i can achieve it?
In Other Words:
What function/method would I have to implement in my View Controller class to handle a click event on a UIButton?
You can make an IBAction for touch up inside in Interface Builder. Then I am assuming you have a UITextField for the text.
Since your not using Interface Builder you need to:
-(void)getStringFromText:(id)sender {
NSString *input = sender.titleLabel;
}
//In some start up method.
[b1 addTarget: target action: #selector(getStringFromText:) forControlEvents: UIControlEventTouchUpInside];
When you declare your UIButtons, you need to put "IBOutlet" before them in your class definition - then you need to to use Interface Builder to link/reference the UIButtons to the ones you have declared in your code.
Once you have done this, you need to develop a (IBAction) method - and have it simply get the "text" property from the calling object. In Interface Builder reference this method for all the buttons for the "touch up" event.
If this isn't clear I will post up code as an example?
I have a small iPhone app which I've created a button with some functionality in. My question is, how can I call this button without actually pressing it?
Any help would be appreciated!
Thanks
If you want to activate whatever target a button is wired to, you can call:
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
(TouchUpInside is the event you'd normally wire a button action to). This way if other targets are added or changed for any button (say for debugging) you don't have to alter your code.
This method is on UIControl which UIButton inherits from, which is why you might have overlooked it at first glance...
Have your button event call a function. You can also manually call the function yourself.
Example:
- (void) btnFunction {
NSLog (#"test");
}
...
UIButton *btn1 = [UIButton buttonWithType:UIButtonRoundedRect];
// other code to set up button goes here
[btn1 addTarget:self action:#selector(btnFunction) forControlEvents:UIControlEventTouchUpInside];
You can also call the function yourself:
[self btnFunction];
Your button shouldn't have functionality, it should just send a message to its target (or call a method, or call a function...).
You're free to send that message to that target yourself.
e.g. Your button's target outlet is connected to an IBAction on your controller. That IBAction is just a method of the form:
- (void) doSomething:(id)sender
In your own code do:
[controller doSomething:self];
It's exactly the same as having your button do it.