views:

225

answers:

2

I'm working on a basic iPhone app to test some events, and I'm running into an error that I can't understand or find any answers for. I'm not using IB at all (aside from the MainWindow.xib it creates).

Right now it's about as basic as it could be.

mainAppDelegate.h

#import <UIKit/UIKit.h>
#import "mainViewController.h"

@interface mainAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    mainViewController *viewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) mainViewController *viewController;

@end

mainAppDelegate.m

#import "mainAppDelegate.h"

@implementation mainAppDelegate

@synthesize window;
@synthesize viewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    self.viewController = [[mainViewController alloc] init];
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    return YES;
}

- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}

@end

mainViewController.h

#import <UIKit/UIKit.h>

@interface mainViewController : UIViewController {

}

- (void)showMenu;

@end

mainViewController.m

#import "mainViewController.h"

@implementation mainViewController

- (void)loadView {
    UIScrollView *mainView = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    mainView.scrollEnabled = YES;
    self.view = mainView;    
    self.view.backgroundColor = [UIColor grayColor];

    [self.view setUserInteractionEnabled:YES];
    [self.view addTarget:self action:@selector(showMenu) forControlEvents:UIControlEventTouchDown];

    [mainView release];
}

- (void)showMenu {
    NSLog(@"Show Menu");
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
    [super viewDidUnload];
}

- (void)dealloc {
    [super dealloc];
}

@end

Now, I get a warning on this line:

[self.view addTarget:self action:@selector(showMenu) forControlEvents:UIControlEventTouchDown];

that says 'UIView may not respond to '-addTarget:action:forControlEvents:'. And this doesn't make sense, because a UIView subclass can certainly respond to addTarget, and I'm calling it on self.view, which must exist because I don't release it until the end of loadView. (and even then it should be retained by the controller)

Looking at a trace shows that the actual error is -[UIScrollView addTarget:action:forControlEvents:]: unrecognized selector sent to instance 0x5f11490

So it looks like it's a problem with the selector itself, but I see nothing wrong with my selector!

I'm pretty baffled by this and any help would be great.

A: 

try this subtle change

[self.view addTarget:self action:@selector(showMenu:)
                               forControlEvents:UIControlEventTouchDown];

and this

- (void)showMenu:(id) sender {
    NSLog(@"Show Menu");
}
Aaron Saunders
+2  A: 

First, classes always start with capital letters....

UIScrollView is a subclass of UIView, not UIControl.

UIControl implements addTarget:action:forControlEvents:. UIScrollView does not. Thus, the runtime error.

If you want something to happen in response to an action taken on the scroll view, set up a delegate for the scroll view. See UIScrollViewDelegate's documentation.

bbum
+1 for `UIControl`. As further insight, `UIControl` is what gives you all of those `UIControlEvents` such as touch down or touch up. If the object isn't a subclass of `UIControl`, then you can't use those events on it. A quick example would be to open up a XIB that has a view in it. Click the view, go into the inspector window and you'll see it has none of those control events. Now if you goto the last tab of the inspector window and make it a `UIControl` subclass instead of `UIView` it magically has all of those events that you can hook up.
iWasRobbed
Thanks that's exactly what I needed to know. I should've known to check that.When you say 'classes always start with capital letters' - is that convention or necessary?
Evan Cordell
Objective-C Convention, though many of us consider it necessary to avoid insanity inducing confusion. :)
bbum