How to delegate functionality or design to other UIViewController - iphone

For example, I have two same buttons in all view controllers. And reaction of these buttons are the same in all view controllers. How I can make this functional in common class and use this class or object in every view controllers?

When you add the couple target/action to the button, you can set the target to a specific class:
[button1 addTarget:myOtherClassInstance action:#selector(doSomethingAction:) forControlEvents:UIControlEventTouchUpInside];
[button2 addTarget:myOtherClassInstance action:#selector(doSomethingAction2:) forControlEvents:UIControlEventTouchUpInside];
and in the myOtherClass.m
- (void)doSomethingAction:(id)sender {
//Do something and maybe check the sender
}
- (void)doSomethingAction2:(id)sender {
//Do some other thing and maybe check the sender
}

you can put the action method in the delegate class , and link the button tap event to this method like this
[yourButton addTarget:yourDelegate action:#selector(yourmethod:) forControlEvents:UIControlEventTouchUpInside];

Related

How can I add more parameters to the selector called by addTarget:action:forControlEvents:?

When the button pressed, I want to push a new view, and I need to pass an NSDictionary object to new DetailViewController ,so the method looks like this:
-(void)displayCourseDetail:(NSDictionary*)dictionary{
self.detailViewController = [[[DetailViewController alloc]init]initWithDictionary:dictionary];
[self presentViewController:detailViewController animated:YES completion:nil];
}
But I don't know how to pass an NSDictionary by this:
[button addTarget:self action:#selector(displayCourseDetail:) forControlEvents:UIControlEventTouchUpInside];
The button was created in code because it's dynamic.
UIButton *button=[UIButton buttonWithType:UIButtonTypeCustom];
button.frame=CGRectMake(_StartX+day*_ButtonWidthWorkday, _StartY+course*_ButtonHeightNormal, _ButtonWidthWorkday-_ButtonMargin, _ButtonHeightNormal-_ButtonMargin);
How can I pass the NSDictionary object to specific view controller when the button is pressed?
You can use:
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
Then in the action method, pass the dictionary:
-(IBAction) buttonClicked:(id)sender{
...
[self performSelector:#selector(displayCourseDetail:) withObject:yourDictionary];
}
You can't add any parameters to the selector called by addTarget:action:forControlEvents:. You need to do some logic to create the dictionary from scratch or get a reference to an existing one in displayCourseDetail:. Once you have that, you can pass it to initWithDictionary the same way you are currently passing the method argument.
I can't help you without seeing a lot more of your code, but I would imagine that however you are accessing the dictionary when creating the button would work if moved into displayCourseDetail: too.
I noticed that when you are making a DetailViewController you call both init and initWithDictionary: which is very likely not correct. You should use initWithDictionary: only.

UIButtons not working on programmatically created UIView

I have a UIViewController which I want to display a UIView that renders as a menu. This menu will have several buttons on it. I wanted to reuse this menu a few different places in my app so I figured I would create a class called ViewFactory that has a method that returns a UIView with these buttons.
On my ViewController I call this method and get the returned UIView and add it as a subview.
This works just fine. I can see the view and all its buttons, however, the buttons do not respond to any touch events. Not sure why this is the case and curious to know what I am doing wrong.
Here is my code for the ViewFactoryClass:
- (UIView *) addCloseRow
{
// UIView container for everything else.
UIView *navRow = [[UIView alloc] initWithFrame:CGRectMake(0,225,350,45)];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.userInteractionEnabled = YES;
[navRow addSubview:button];
[button addTarget:self action:#selector(closeButtonTouchDownEvent) forControlEvents: UIControlEventTouchDown];
navRow.userInteractionEnabled = YES;
return navRow;
}
In my main NavigationController class here is how I am calling and getting the UIView:
ViewFactory *factory = [[ViewFactory alloc] init];
[self.navigationController.navigationBar addSubview:[factory MainNavigationUIView]];
Again, the UIView shows up but the buttons never respond to anything.
You added the button with target and selector for ViewFactoryClass
And now you are creating instance and trying to call an action from ViewFactory class.
You can change the method to something like this:
- (UIView *) addCloseRow : (id)object {
...
[button addTarget:[object class] action:#selector(closeButtonTouchDownEvent) forControlEvents: UIControlEventTouchDown];
...
}

Custom UIButton's action does not called

I have subclass of UIButton:
#interface MyButton : UIButton
- (IBAction) buttonPressed:(id)sender;
#end
#implementation MyButton
- (void)awakeFromNib
{
NSLog(#"awake from nib");
}
- (IBAction) buttonPressed:(id)sender
{
NSLog(#"button pressed");
}
#end
I add a button in my parent xib, set it's class to MyButton, and connected it's action to First Responder's method buttonPressed.
When I start an application and load my parent xib with my button inside, than awakeFromNib from MyButton class is called. But when I press the button, nothing happens. I was expecting that my method buttonPressed from MyButton class will be called.
I supposed, that my button's view is the first responder in responder chain, but apparently I do something wrong.
Could you please suggest something?
If you want that your button always call the method declared add the code above to the awakeFromNib method
[self addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
and later when you added it to a view controller do not assign it a new action, this way it will always call your method.
Depending on what you are doing with the button - there is no real need to make a subclass.
Here is some code how to make a simple button that triggers a method:
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton setFrame:CGRectMake(10, 10, 100, 30)];
[myButton setTitle:#"Title" forState:UIControlStateNormal];
[myButton addTarget:self action:#selector(myMethod:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:myButton];
the add target bit tells the button to trigger the given selector when the user touches up inside the button (taps it). The target is the object that the selector is in.
Hope this helps, you should not need to subclass UIButton unless you have custom layouts or specific custom functionality for it.
Since you want to handle the action from the button code itself, you may have to override this method - (void)sendActionsForControlEvents:(UIControlEvents)controlEvents and handle your event as if it was sent to your button;

How to handle a UIView's control events from a UIViewController.

I have subclassed a UIView. I am adding it as a subview of a UIViewController view. I have a button in the UIView. What I want is to handle the button click inside my UIViewController, where I will remove the UIView from superview and push another UIViewController. How can I do this.
You must attach the target with your UIButton. addTarget method is used for getting the event when you click on button and defined in UIControl class which is direct super class of UIButton
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
Code to receive the event for Button touch.
[myButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
Implementation for the action.
-(void) buttonClicked:(id) sender {
UIButton* myButton = (UIButton*)sender;
//Put your code here
}

how to perform a segue

I would like implement a button to show another view. I have defined the destination ViewController in Storyboard & created a segue (of type push) and gave it an identifier.
In my root view controller
some method ...
UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[btn addTarget:self action:#selector(showDetailView:) forControlEvents:UIControlEventTouchUpInside];
and
- (IBAction)showDetailView:(id)sender {
[self performSegueWithIdentifier:#"ShowDetail" sender:sender];
}
however it doesn't do anything. I hear a Segue is an object. do I need to have a reference to it / synthesize it in my root view controller class? Any tip would be appreciated. Thank you.
Edit:
Make sure your root view controller is embedded in a navigation controller. if it isn't, select your view controller in the storyboard designer and choose Editor->Embed In->Navigation Controller in the menu.
Original:
Double-check the Identifier (storyboard-code) and try setting sender to self. If that doesn't work you can create a Segue object yourself in code.