I have subclassed the UIToolbar to make it easier to implement a safari next, previous, done sort of thing.
It all worked fine when i was adding it directly (ie not subclassing) but now that i am, it crashes every time i click one of the buttons with
-[keyboardToolBar hideKeyboard:]: unrecognized selector sent to instance
This is the first time i have attempted to subclass something so im not sure if i have done something the wrong way.
Code for the subclass
@interface keyboardToolBar : UIToolbar {
UIToolbar *keyboard;
UIBarItem *previous;
UIBarItem *next;
UIBarItem *done;
}
@property (nonatomic, retain) UIToolbar *keyboard;
@property (nonatomic, retain) UIBarItem *previous;
@property (nonatomic, retain) UIBarItem *next;
@property (nonatomic, retain) UIBarItem *done;
-(void)previousField;
-(void)nextField;
-(void)hideKeyboard;
@end
#import "keyboardToolBar.h"
@implementation keyboardToolBar
@synthesize keyboard, previous, done, next;
-(UIToolbar*)initWithFrame:(CGRect)frame{
//Create a new toolbar
keyboard = [[UIToolbar alloc]initWithFrame:frame];
//Create all the buttons and point them to methods
UIBarButtonItem *previousButton = [[UIBarButtonItem alloc] initWithTitle:@"Previous"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(previousField:)];
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:@"Next"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(nextField:)];
UIBarButtonItem *filler = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(hideKeyboard:)];
//Set the width of both of the buttons to make it look pritty
previousButton.width = 70.0f;
nextButton.width = 70.0f;
self.previous = previousButton;
self.next = nextButton;
self.done = doneButton;
//Add the buttons to the toolbar
[keyboard setItems:[[[NSArray alloc] initWithObjects:self.previous, self.next, filler, self.done, nil] autorelease]];
//Release the buttons
[previous release];
[next release];
[filler release];
[done release];
//return the shiny new toolbar
return keyboard;
}
-(void)previousField{
}
-(void)nextField{
}
-(void)hideKeyboard{
NSLog(@"hello");
}
@end
and is called using UIToolbar *keyboard = [[keyboardToolBar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)];
I have tried everything i can think of but still get the same error. Im sure i am just not retaining something somewhere of pointing the buttons to the wrong place but any help would be muchly appreciated Thanks开发者_运维百科 Darc
The problem here is that your buttons are calling functions that take an input, but your functions do not take an input:
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(hideKeyboard:)];
This means that there must be a method hideKeyboard:(id)sender
. But you have
-(void)hideKeyboard{
NSLog(@"hello");
}
Either add the input to the function or remove the :
from the selector call.
you effectively wrote it as a class method, here is a little bit better version, because of memory management issues etc.
-(UIToolbar*)initWithFrame:(CGRect)frame{ //Create a new toolbar
if ((self = [super initWithFrame:frame]))
//Create all the buttons and point them to methods
previous = [[UIBarButtonItem alloc] initWithTitle:@"Previous" style:UIBarButtonItemStyleBordered target:self action:@selector(previousField:)];
next = [[UIBarButtonItem alloc] initWithTitle:@"Next" style:UIBarButtonItemStyleBordered target:self action:@selector(nextField:)];
UIBarButtonItem *filler = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
done = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleBordered target:self action:@selector(hideKeyboard:)];
//Set the width of both of the buttons to make it look pritty
previous.width = 70.0f;
next.width = 70.0f;
//Add the buttons to the toolbar
[keyboard setItems:[[[NSArray alloc] initWithObjects:previous, next, filler, done, nil] autorelease]];
//Release the buttons
[previous release];
[next release];
[filler release];
[done release];
//return the shiny new toolbar
return self;
}
also fix your methods to be either
@selector(someAction)
to match -(void)someAction;
or @selector(someAction:)
to match -(void)someAction:(id)sender;
also no reason to keep a reference to UIToolBar * keyboard, because you want that to be self. actually probably no reason to keep references to the buttons at all unless you will need to change their titles or action/target pairs later.
You (or something you're doing) is calling hideKeyboard:
(note the colon, indicating that the method has one argument.). However, the hideKeyboard
method you've implemented, doesn't take any arguments.
Most likely, hideKeyboard
should be changed to:
- (void)hideKeyboard:(id)sender {
NSLog(@"hello");
}
As an aside, the usual style for class names is capitalized, so your subclass should be KeyboardToolBar
(and I'd also recommend keeping the same camel case as Apple's classes, so KeyboardToolbar
would be best).
精彩评论