Question

I need to programmatically delegate various events which occur in the main view to handlers that are instantiated by the main ViewController.

In other words, instead of having the ViewController handle all the events for a given view I would like to have separate instantiated objects handle the events for subsections of the overall view.

A numbered bulleted list describing how to implement this, or a link to a numbered bulleted list would be highly helpful. If you included an explanation which used examples from Java's Swing API as analogous operations you would earn a special place in my heart.

Here is my current half-baked code. I include it so you know I have tried to solve this before resorting to Stack Overflow.

TCH_MainViewController.m

#import "TCH_MainViewController.h"
#import "TCH_MainViewButtonHandler.h"

@interface TCH_MainViewController ()

@property (nonatomic, weak) IBOutlet UILabel *titleLabel;
@property (nonatomic, weak) TCH_MainViewButtonHandler *buttonHandler;
@property (nonatomic, weak) UIButton *changeColorButton;

@end

@implementation TCH_MainViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.


    [_changeColorButton addTarget:_buttonHandler action:@selector(changeColorButton) forControlEvents:UIControlEventTouchUpInside];


}

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

@end

TCH_MainViewButtonHandler.m

#import "TCH_MainViewButtonHandler.h"

@implementation TCH_MainViewButtonHandler

- (IBAction)changeLabelColor:(id)sender{

}

-(void)awakeFromNib{

}

@end
Was it helpful?

Solution

you do have the selector signature wrong, but you also need to initialize your handler class first either directly or lazily. Oh yea, and the property for the handler should be strong, not weak as you need your main class to retain the handler class. I'm assuming the button is on a Storyboard or Xib file. In that case it's good for the button to be weak because the Storyboard is retaining it strongly. If you class did as well, that would create a retain cycle.

Correct the property:

@property (nonatomic, strong) TCH_MainViewButtonHandler *buttonHandler;

Initialize the class before you set the selector on the button.

self.buttonHandler = [TCH_MainViewButtonHandler alloc]init];

note: probably a better practice to access the property via self rather then its instance _button..

then set the target on the button:

[self.changeColorButton addTarget:self.buttonHandler action:@selector(changeColorButton:) forControlEvents:UIControlEventTouchUpInside];

Note: the colon on the end of the selector is usually added if you let Xcode autocomplete. It references the parameter "sender" in this case.

Add a little NSLog(@"button pressed"); in the button action in your button handler and see if that does not get called. It should.

Now, normally UI events like button pushes are not normally delegated away because they end up doing something to the view and that needs to come from the controller managing the view. Although for a network call you might do it. If your button push is affecting the view i.e updating an label, you'll need to come back to the view controller for that purpose. So you have to think through that.

However, per your question, this answer should get you to the next step.

hope that helps, best wishes.

OTHER TIPS

Your selector is @selector(changeColorButton) when I believe it should be @selector(changeLabelColor:).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top