开发者

Crash when subclassing UIToolbar

开发者 https://www.devze.com 2023-03-13 16:04 出处:网络
I have subclassed the UIToolbar to make it easier to implement a safari next, previous, done sort of thing.

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).

0

精彩评论

暂无评论...
验证码 换一张
取 消