Reputation: 3807
Problem:
I can't get my UIButton to send my Class an Event call
Here is what I tried first:
I made a class which extends UIViewController, called Viewer
#import "Viewer.h"
#import "MainScreen.h"
@implementation Viewer
- (void)viewDidLoad
{
MainScreen* main = [[MainScreen alloc]init: self];
[main show];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
@end
then:
MainScreen:
#import "MainScreen.h"
#import "Viewer.h"
@implementation MainScreen
{
IBOutlet UIButton* singlePlayerButton;
IBOutlet UIView* view;
Viewer* viewer;
}
- (id)init:(Viewer*) theViewer
{
self = [super init];
viewer = theViewer;
return self;
}
- (void)show
{
[[NSBundle mainBundle] loadNibNamed:@"MainScreenLayout" owner:self options:nil];
[viewer.view addSubview:view];
}
- (IBAction)buttonPressed:(id)sender
{
NSLog(@"A button was pressed!");
}
@end
Then I created an NIB called MainScreenLayout.xib
Here is what it looks like:
As you can see, I have four buttons but the only one that is connected to anything is the Single-Player button I also have the UIView connected to view.
Now, I linked the action to the Single-Player button like this:
buttonPressed
is my method that I want to have called when the button is pressed, so I ctrl-clicked on First Responder and then clicked on the circle next to buttonPressed
and then dragged it on top of the Single-Player button. Then the next dialog window popped up and I clicked on Touch up Inside. Here is what the Received Actions window looks like:
Now, I thought at this point it should work. I ran it on my iPhone Simulator and pressed the button.
Just so there is no question of whither or not I'm competent, here is a picture of me actually clicking the button:
I got no output whatsoever. Then I went to my code and looked at the method. This is what it looks like:
as you can see, the oval is not filled, meaning that the method is not paired. So naturally I thought it was being overridden by another method. So here is what the method looks like now:
- (IBAction)aVerySpecificMethodNameForMyButtonListener:(id)sender
{
NSLog(@"A button was pressed!");
}
Then I went back to my NIB window, unpaired my Single-Player button and then repaired it to aVerySpecificMethodNameForMyButtonListener
. Now this is what it looks like:
Then I ran it again and still nothing when I pressed the button. Then I went back to the code:
(insert frustration here)
At this point I restarted Xcode and the Simulator and looked over everything again and it still didn't work.
This is what I tried next which seems about a billion times more simple:
- (void)show
{
[[NSBundle mainBundle] loadNibNamed:@"MainScreenLayout" owner:self options:nil];
[viewer.view addSubview:view];
[singlePlayerButton addTarget:self action:@selector(aVerySpecificMethodNameForMyButtonListener:) forControlEvents:UIControlEventTouchUpInside];
}
I replaced with my show
method with the one above. The only thing different is the last line. I disconnected my method from the Single-Player button in the NIB. Then I ran it and I got excited for a second because I got some output. Here is what I got:
(lldb)
Very helpful output C debugger, as always. I spent the next few hours on SO trying to find out what I'm doing wrong. I've tried countless examples and none of them worked.
Does anybody see what I'm doing wrong here? Is it just Xcode being flakey?
Thanks for reading!! All relevant answers are welcomed!
UPDATE:
I also tried changing the declaration of UIButton to a property in the Header file:
#import <Foundation/Foundation.h>
#import "Viewer.h"
@interface MainScreen : NSObject
{
IBOutlet UIView* view;
Viewer* viewer;
}
@property (weak, nonatomic) IBOutlet UIButton* singlePlayerButton;
- (id)init:(Viewer*) theViewer;
- (void)show;
- (IBAction)aVerySpecificMethodNameForMyButtonListener:(id)sender;
@end
Thus here is what I changed in MainScreen.m to comply:
#import "MainScreen.h"
#import "Viewer.h"
@implementation MainScreen
- (id)init:(Viewer*) theViewer
{
self = [super init];
viewer = theViewer;
return self;
}
@synthesize singlePlayerButton;
- (void)show
{
[[NSBundle mainBundle] loadNibNamed:@"MainScreenLayout" owner:self options:nil];
[viewer.view addSubview:view];
[singlePlayerButton addTarget:self action:@selector(aVerySpecificMethodNameForMyButtonListener:) forControlEvents:UIControlEventTouchUpInside];
}
- (IBAction)aVerySpecificMethodNameForMyButtonListener:(id)sender
{
NSLog(@"A button was pressed!");
}
@end
Now there are no variable declarations inside of the MainScreen.m file, I moved them all to the Header. The circles next to singlePlayerButton
and view
are still filled in but the bubble next to the method is not. I ran the code again and got the same output.
Upvotes: 1
Views: 639
Reputation: 1029
So I'd have put this in a comment because its really just a suggestion however I dont have the rep yet so sorry to get your hopes up, but I believe the touch event's scope is only inside the UIView in which it happens. When the touch up event gets triggered it doesn't get passed to the UIView's handler (MainScreen class) and so the event's listener method does not get called... but that you are able to link it in the interface builder to the button is baffling to me, so i could be way off.
Anyways, where I think you should go next is to make your MainScreen a UIView object and see what that does for event handling of the buttons in the view.
Upvotes: 1