2012-01-12 83 views
0

我按照教程http://www.youtube.com/watch?v=YgeuauhsDhQ创建键盘上方的上一个,下一个完成按钮,并用键盘向上滑动。iPhone键盘工具栏类

但是,我注意到他正在对特定视图进行操作,我不希望将其复制/粘贴到具有文本字段的每个视图中。我尝试为此做一个课,但后来意识到他辞去了当前焦点领域的键盘。

是否有人知道一个类已经在那里,所以我不必为每个具有文本字段的视图控制器创建此?或者知道我如何修改他的版本以作为我可以导入到视图控制器的类来工作?

对不起,我是一个新的iPhone开发。

//KeyboardToolbar.h 

#import <Foundation/Foundation.h> 

@interface KeyboardToolbar : NSObject 
{ 
    UIToolbar *keyboardToolbar; 
} 

@property (nonatomic, retain) UIToolbar *keyboardToolbar; 

-(void)resignKeyboard:(id)sender; 
-(void)previousField:(id)sender; 
-(void)nextField:(id)sender; 
@end 

//KeyboardToolbar.m 
#import "KeyboardToolbar.h" 


@implementation KeyboardToolbar 

@synthesize keyboardToolbar; 

- (void)loadToolbar 
{ 
    if (keyboardToolbar == nil) { 

     keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 44.0)]; 

     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 *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 

     UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(resignKeyboard:)]; 

     [keyboardToolbar setItems:[[NSArray alloc] initWithObjects:previousButton, nextButton, extraSpace, doneButton, nil]]; 
    } 
} 

- (void)resignKeyboard:(id)sender 
{ 
    //Resign the keyboard here? I would need to get the element with the keyboard then hide it. 
} 

@end 

我将如何让这个类更加动态的,所以我可以在我所有的意见很少复制/粘贴到每个控制器使用它。

回答

3

我也是新手,但我想我可以帮忙。我做了类似的事情。我设置了一个辅助对象来充当用户当前正在与之交互的任何视图控制器的委托。您将编写用于显示工具栏的代码。您将在助手(委托)类的.m文件中实现这些方法。添加你的助手类作为UIKeyboardDidShowNotification的观察者。所以,在我的UIViewControllers的viewDidLoad中,我将委托设置为我的帮助对象。然后,当键盘出现在当前视图控制器上时,通知被发送到委托(辅助对象)。 这里有一个小码澄清: 在辅助对象的init方法:

 [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(keyboardWasShown:) 
               name:UIKeyboardDidShowNotification 
               object:nil]; 

然后,在您的辅助对象的.m文件,在keyboardWasShown:,呼叫[自makeToolbar]或任何被称为你的方法。对不起,冗长。就像我说的,我很新,但我希望这有助于。

编辑:所以我做了一个简单的小测试/插图。这是我的ViewController类的.h。这是包含UITextFields的ViewController,它们都会显示一个键盘并通过委托方法向其添加工具栏。对不起,冗长的回应,但我认为这将是最有用的,只是给你所有的东西为我工作。

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

@interface ViewController : UIViewController <UITextFieldDelegate> { 
    //Outlets for 2 UITextFields, added in IB. Selecting either will add the toolbar to your keyboard as long as the delegate is assigned and the methods in the delegate are implemented as shown. 
    IBOutlet UITextField *myTextField; 
    IBOutlet UITextField *myOtherTextField; 

    //we'll need to set the delegate for this class, so go ahead and declare a variable and make it a property (and synthesize it in the .m). 
    id delegate; 
} 

@property (nonatomic, strong) id delegate; 

@end 

ViewController.m:

@implementation ViewController 
@synthesize delegate; 

//removed method stubs and only left my modifications to the template. 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    //create an instance of your delegate class and set it as the view controller's delegate. 
    //the text fields need their parent as the delegate, and the parent in turn assigns the helper class as its delegate. 
    //really this is the whole point, that you can just assign delegates to your view 
    //controllers and text fields and they can all access the one method implementation 
    //instead of each having to implement it separately themselves. 
    [myTextField setDelegate:self]; 
    [myOtherTextField setDelegate:self]; 
    TextFieldDelegate *myDelegate = [[TextFieldDelegate alloc] init]; 
    [self setDelegate: myDelegate]; 

    //set the delegate's currentViewController property so that we can add a subview to this View. 
    [delegate setCurrentViewController:self]; 

} 

- (void)textFieldDidBeginEditing:(UITextField *)textField { 
    //set the delegate's current text field property so that we can resignFirstResponder. 
    [delegate setCurrentTextField:textField]; 
} 

@end

现在,这里的委托类: TextFieldDelegate.h:

#import <Foundation/Foundation.h> 
#import <UIKit/UIKit.h> 

@interface TextFieldDelegate : UIViewController <UITextFieldDelegate> { 
    UIViewController *currentViewController; 
    UITextField *currentTextField; 
    UIToolbar *keyboardToolbar; 
    CGSize kbSize; 
} 

- (void)loadToolbar; 

@property (nonatomic, strong) UIViewController *currentViewController; 
@property (nonatomic, strong) UITextField *currentTextField; 

@end 

和委托执行: TextFieldDelegate.m:

#import "TextFieldDelegate.h" 

@implementation TextFieldDelegate 

//synthesize properties so that View Controllers can set them as needed. 
@synthesize currentViewController, currentTextField; 

- (id)init { 
    self = [super init]; 
    if (self) { 
     //register for the keyboard did show notification 
     [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(keyboardWasShown:) 
                name:UIKeyboardDidShowNotification 
                object:nil]; 
    } 
    return self; 
} 

- (void)keyboardWasShown:(NSNotification *)aNotification { 
    //get the keyboard size for positioning the toolbar. (depending on where you want it, I guess, I was just imagining it directly above the keyboard. 
    NSDictionary *info = [aNotification userInfo]; 
    kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; 
    //call the method to make the toolbar appear. 
    [self loadToolbar]; 
} 

- (void)loadToolbar 
{ 
    if (keyboardToolbar == nil) { 

     //setting the position of the toolbar. 
     CGRect frameRect = self.view.frame; 
     frameRect.size.height -= kbSize.height; 

     keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, frameRect.size.height - 60.0, 320.0, 60.0)]; 

     //your code for toolbar setup. 
     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 *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 

     UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(resignKeyboard:)]; 

     [keyboardToolbar setItems:[[NSArray alloc] initWithObjects:previousButton, nextButton, extraSpace, doneButton, nil]]; 

     //this line sends a message to the currently active view controller, telling it to add as a subview the toolbar that we have just created. 
     [[currentViewController view] addSubview:keyboardToolbar]; 
    } 
} 

- (void)resignKeyboard:(id)sender { 
    [currentTextField resignFirstResponder]; 
    [keyboardToolbar removeFromSuperview]; 
    //set the toolbar to nil so that when you touch the other text field, it will build  again. 
    keyboardToolbar = nil; 
} 

@end 

所以,它就是这样。就像我说的,我也是新的。但我希望这有助于。

@jostster 编辑:哦,如果您将调用自定义委托方法loadToolbar移动到ViewController的textFieldDidBeginEditing方法,它的工作原理。在ViewController.m

- (void)textFieldDidBeginEditing:(UITextField *)textField { 
    //set the delegate's current text field property so that we can resignFirstResponder. 
    [delegate setCurrentTextField:textField]; 
    [delegate loadToolbar]; 
} 

然后你可以删除在委托执行的[自loadToolbar]从keyboardWasShown电话。

编辑:让你的下一个和上一个按钮工作,首先给你的委托一个属性:NSArray * textFieldArray。然后,在你的视图控制器中,创建一个你的文本字段的数组(我们称之为tfArray),然后执行[delegate setTextFieldArray:tfArray];然后实现您的previousField:和nextField:方法是这样的:

- (void)previousField:(id)sender { 
    //get the index in the array of your currently active textField 
    int activeIndex = [textFieldArray indexOfObject:currentTextField]; 
    //make sure you're not going to try to access an empty spot in the array 
    if (activeIndex > 0) { 
    UITextField *previousField = [textFieldArray objectAtIndex:activeIndex - 1]; 
    [previousField becomeFirstResponder]; 
    } 
} 
//same again but with a plus sign 
- (void)nextField:(id)sender { 
    int activeIndex = [textFieldArray indexOfObject:currentTextField]; 

    if (activeIndex < 1) { 
    UITextField *nextField = [textFieldArray objectAtIndex:activeIndex + 1]; 
    [nextField becomeFirstResponder]; 
    } 
} 

有可能这样做,但代码量的清洁方法是微乎其微的,我不喜欢打字两次是大的交易。这是它虽然要点,如果你有一大堆的文本字段,以推进通过,你只是想这样说:

if (activeIndex < [textFieldArray count]) { 
//advance to the next textField 
} 
+0

我编辑我的OP包含的代码,如果你能协助执行。 – Bot 2012-01-12 23:54:23

+0

谢谢!此外,当您进行更新时,请确保您发布的评论是@和您想要关注的人名,以便我们可以看到我们有更新。一个问题是,在youtube视频中,工具栏将随键盘滑动,并将改变方向。我注意到这个也没有做。 – Bot 2012-01-13 16:15:11

+0

好吧我通过'keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0,0.0,self.view.bounds.size.width,44.0)];'而不是'[[currentViewController视图] addSubview :keyboardToolbar];'使用'currentTextField.inputAccessoryView = keyboardToolbar;'但是我必须点击该字段,然后出现另一个字段才能显示工具栏。你知道如何得到这个工作在第一个文本字段点击? – Bot 2012-01-13 16:33:54