views:

1122

answers:

2

Hi. I tried a lot of stuff, still no result.

So I have the following button created programatically in a subclass of UIViewController:

    rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
    rightButton.frame = CGRectMake(0.0, 0.0, 110.0, 40.0);
    rightButton.titleLabel.font = [UIFont fontWithName:GAME_FONT_NAME_STRING size:20.0];
    [rightButton setTitle:@"MyTitle" forState:UIControlStateNormal];
    rightButton.backgroundColor = [UIColor clearColor];
    [rightButton setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
    [rightButton setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
    [rightButton setBackgroundImage:normalImage forState:UIControlStateNormal];
    [rightButton setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];
    [rightButton addTarget:self action:@selector(myButton) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:rightButton];

where the selector is:

- (void)myButton;

I tried everything:

- (void)myButton;
- (void)myButton:(id)sender;
- (void)myButton:(id)sender forEvent:(UIEvent *)event;
- (IBAction)myButton;
- (IBAction)myButton:(id)sender;
- (IBAction)myButton:(id)sender forEvent:(UIEvent *)event;

and the corresponding selectors, of course:

[rightButton addTarget:self action:@selector(myButton) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton:) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton:forEvent:) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton:) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton:forEvent:) forControlEvents:UIControlEventTouchUpInside];

The result is always an uncaught exception - [NSObject doesNotRecognizeSelector:]. However, the usual backtrace of the program is:

#0  0x92a6bedb in objc_msgSend ()
#1  0x03b0a430 in ?? ()
#2  0x00306b4e in -[UIControl sendAction:to:forEvent:] ()
#3  0x00308d6f in -[UIControl(Internal) _sendActionsForEvents:withEvent:] ()
#4  0x00307abb in -[UIControl touchesEnded:withEvent:] ()
#5  0x002bcddf in -[UIWindow _sendTouchesForEvent:] ()
#6  0x002a67c8 in -[UIApplication sendEvent:] ()
#7  0x002ad061 in _UIApplicationHandleEvent ()
#8  0x02498d59 in PurpleEventCallback ()
#9  0x01cabb80 in CFRunLoopRunSpecific ()
#10 0x01caac48 in CFRunLoopRunInMode ()
#11 0x02497615 in GSEventRunModal ()
#12 0x024976da in GSEventRun ()
#13 0x002adfaf in UIApplicationMain ()

So what is the problem with that button?

PS: I am using the iPhone SDK 3.1.3


Update!

The following code in the AppDelegate (no declarations in the interface):

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    UIButton *test = [[UIButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 100.0)];
    [test setTitle:@"Title" forState:UIControlStateNormal];
    UIImage *bg = [UIImage imageNamed:...];
    [test setBackgroundImage:bg forState:UIControlStateNormal];
    [test addTarget:self action:@selector(testAction) forControlEvents:UIControlEventTouchUpInside];
    [window addSubview:test];
    [test release];
    [window makeKeyAndVisible];
}

- (void)testAction {
    NSLog(@"Write something...");
}

works perfectly!

But if I create an empty UIViewController with the same code:

- (void)viewDidLoad {
    UIButton *test = [[UIButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 100.0)];
    [test setTitle:@"Title" forState:UIControlStateNormal];
    UIImage *bg = [UIImage imageNamed:...];
    [test setBackgroundImage:bg forState:UIControlStateNormal];
    [test addTarget:self action:@selector(testAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:test];
    [test release];
    [window makeKeyAndVisible];
}

- (void)testAction {
    NSLog(@"Write something...");
}

I get this mysterious error. :-( Help!

A: 

where's myButton being declared? if it is synthesized, then instead of

rightButton = [UIButton buttonWithType:UIButtonTypeCustom];

use

self.rightButton = [UIButton buttonWithType:UIButtonTypeCustom];

that should work. If not, please post how you are declaring the property.

Bach
@BachI do not believe that this is the issue here. This view controller creates it's view programatically (no xib file at all). The button is just an instance variable (not a property) in the class, so: self.rightButton = ...does not compile at all.I even created a button right in the code. UIButton *button2 = [UIButton buttonWithType:UIButtonTypeCustom]; ... [self.view addSubview:button2];When I do not add a target and an action the buttons render and act normally. When I add the functionality (addTarget:action:forEvents:) the exception is thrown on a click.
Teodor
+1  A: 

THE SOLUTION!

My problem was that I used the following code in the AppDelegate:

UIViewController *controller = [[MyCustomController alloc] init];
[window addSubview:controller.view];
[controller release];

So only the view property of the view controller was retained and everything else was purged. The view controller did not have any functionality (no touch events, no instance methods). That is why the addTarget:action:forEvents: did not work.

So, do it smart - release your view controllers in the dealloc of the AppDelegate. ;)

Teodor