1

What I have is three button at the top of my app.

Those three buttons will always appear on all view controller.

When I click button, respective action will be taken.

As we have this in all viewcontroller, what I am planning is I will have method defined somewhere which I will call on clicking this button.

I am doing this because I will have method written once and call them anywhere.

ELse I had to write method for all view controller and if there are changes later, I will have to do for all view controllers.

Any idea how can I achieve the same?

What I want to do is define some method in one UIViewController and call that method in many different ViewController.

Fahim Parkar
  • 30,974
  • 45
  • 160
  • 276

6 Answers6

2

Consider creating your own container view controller and add your true content view controllers as children (using addChildViewController:). Then your container view controller can manage the global buttons and their actions without affecting any of the actual content view controllers.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • nice point... just to clarify, let's say I made GlobalViewController and have the button action in this viewcontroller... now I will create another class which is subclass of GlobalViewController (`@interface WelcomeViewController : GlobalViewController`). Right? – Fahim Parkar Sep 25 '13 at 21:47
  • but in this case, I believe I need to create button programmatically as I connect using storyboard to my GlobalViewController. Right? – Fahim Parkar Sep 25 '13 at 21:50
  • No, you wouldn't usually subclass the 'GlobalViewController'. There isn't really any good reason to. You can have the view controllers defined in your storyboard and load them by identifier. – Wain Sep 25 '13 at 21:54
  • can you check what I have done and let me know if this is fine? – Fahim Parkar Sep 25 '13 at 22:05
1

Another technique aside from having a container view controller is to have each of your viewControllers subclass another viewcontroller in your project.

@interface MainViewController : UIViewController; // implements your buttons and their actions

@interface OneViewController : MainViewController;
@interface TwoViewController : MainViewController;
@interface ThreeViewController : MainViewController;
bneely
  • 9,083
  • 4
  • 38
  • 46
  • can you see my comments in Wain answer? do you agree? – Fahim Parkar Sep 25 '13 at 21:51
  • @Wain's answer is slightly different. Take a look at the `UIViewController` documentation and decide if you want to use the child view controller arrangement. – bneely Sep 25 '13 at 21:52
  • in your case, I will have to create button programmatically... right? else I can't call action defined in MainViewController for OneViewController... right? – Fahim Parkar Sep 25 '13 at 21:56
  • OneViewController subclasses MainViewController, and inherits all of MainViewController's instance variables and methods. – bneely Sep 25 '13 at 21:58
1

Although subclassing is an option, using Objective-C categories will give you greater flexibility.

Create a category that extends UIViewController:

@interface UIViewController (SharedLogic)

- (void)didPressFirstButton:(id)sender;
- (void)didPressSecondButton:(id)sender;
- (void)didPressThirdButton:(id)sender;

@end

Whatever classes specifies the target/action pair for each button will need to #import this category, but otherwise you should get the behavior you want.

isaac
  • 4,867
  • 1
  • 21
  • 31
0

You could do this with delegates...here's a nice explanation of this:

How do I set up a simple delegate to communicate between two view controllers?

Community
  • 1
  • 1
Jim
  • 2,300
  • 1
  • 19
  • 43
0

What I did is as below and it's working.

Created UIViewController as TopBarViewController which is common for all.

TopBarViewController.h

#import <UIKit/UIKit.h>
@interface TopBarViewController : UIViewController
- (IBAction)clickedSetting:(id)sender;
@end

TopBarViewController.m

#import "TopBarViewController.h"
@interface TopBarViewController ()
@end
@implementation TopBarViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)clickedSetting:(id)sender {
    NSLog(@"clickedSetting-TopBar");
    // do your action here
}

@end

Now when I click button in MyViewController, I call action as below.

- (IBAction)clickedSetting:(id)sender {
    NSLog(@"self-clickedSetting");
    topBarViewCon = [[TopBarViewController alloc] init];
    [topBarViewCon clickedSetting:nil];
}

I have @property (nonatomic, retain) TopBarViewController *topBarViewCon; in .h file & synthesize this property in .m file.

Is this right way is this is wrong way?

Fahim Parkar
  • 30,974
  • 45
  • 160
  • 276
  • If you are trying to follow my answer then this is the wrong way. You should have 1 instance of `TopBarViewController` which is created by the app delegate and is the container for your other view controllers. What you have is all of the other view controllers creating instances of `TopBarViewController` to handle the button selection - very wasteful and not a good structure. – Wain Sep 25 '13 at 22:09
  • @Wain : I can create in Appdelegate, but TopBarViewController is only used after user login in my system (means after first 5-6 view controller). So can I ignore in view controller when I don't want to use them? The problem is I don't have same structure for full app... – Fahim Parkar Sep 25 '13 at 22:17
  • Ok, so after login you would create the `TopBarViewController` instance, add at least 1 child view controller and and push it to the screen. Please read https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html – Wain Sep 25 '13 at 22:19
0

Consider using NSNotificationCenter to broadcast UI events to different places in your codebase.

hundreth
  • 841
  • 4
  • 8