我也是这方面的新手,但我想我可以提供帮助。我做了类似的事情。我设置了一个辅助对象来充当用户当前正在与之交互的任何视图控制器的委托。您将编写代码以显示工具栏。您将在助手(委托)类的 .m 文件中实现这些方法。将您的助手类添加为 UIKeyboardDidShowNotification 的观察者。因此,在我的 UIViewControllers 的 viewDidLoad 中,我将委托设置为我的助手对象。然后,当当前视图控制器上出现键盘时,通知将发送到委托(帮助对象)。
这里有一个小代码来澄清:
在辅助对象的 init 方法中:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
然后,在您的辅助对象的 .m 文件中,在 keyboardWasShown: 中,调用 [self 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];
}
@结束
现在是委托类:
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];
}
然后您可以在委托实现中从keyboardWasShown 中删除[self loadToolbar] 调用。
编辑:要让你的下一个和上一个按钮工作,首先给你的委托一个属性: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
}