问题
I am successfully adding a done button to my number pad with this handy code below. But I have an email button that launches the MFMailComposeViewController. How would I make sure the done button does not appear on the email keyboard?
//
// UIViewController+NumPadReturn.m
// iGenerateRandomNumbers
//
// Created by on 12/4/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "UIViewController+NumPadReturn.h"
@implementation UIViewController (NumPadReturn)
-(void) viewDidLoad{
// add observer for the respective notifications (depending on the os version)
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
}
}
- (void)keyboardWillShow:(NSNotification *)note {
// if clause is just an additional precaution, you could also dismiss it
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 3.2) {
[self addButtonToKeyboard];
}
}
- (void)keyboardDidShow:(NSNotification *)note {
// if clause is just an additional precaution, you could also dismiss it
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[self addButtonToKeyboard];
}
}
- (void)addButtonToKeyboard {
// create custom button
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 163, 106, 53);
doneButton.adjustsImageWhenHighlighted = NO;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.0) {
[doneButton setImage:[UIImage imageNamed:@"DoneUp3.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"DoneDown3.png"] forState:UIControlStateHighlighted];
} else {
[doneButton setImage:[UIImage imageNamed:@"DoneUp.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"DoneDown.png"] forState:UIControlStateHighlighted];
}
[doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];
// locate keyboard view
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++) {
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
if([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
[keyboard addSubview:doneButton];
} else {
if([[keyboard description] hasPrefix:@"<UIKeyboard"] == YES)
[keyboard addSubview:doneButton];
}
}
}
- (void)doneButton:(id)sender {
NSLog(@"doneButton");
[self.view endEditing:TRUE];
}
@end
I am trying to extend the UIViewController so it automatically does this when I import this subclass, so a boolean flag in my application probably won't work.
回答1:
For iOS 3.2+, you should not use this hack anymore, anyway. Instead, assign your custom view to your control's inputAccessoryView
property.
回答2:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
UIButton *myDoneButton = [self GetKeyboardDoneButton];
myMinText.inputAccessoryView = myDoneButton;
myMaxText.inputAccessoryView = myDoneButton;
}
- (UIButton *)GetKeyboardDoneButton {
// create custom button
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(-100, 163, 106, 53);
doneButton.adjustsImageWhenHighlighted = NO;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.0) {
[doneButton setImage:[UIImage imageNamed:@"DoneUp3.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"DoneDown3.png"] forState:UIControlStateHighlighted];
} else {
[doneButton setImage:[UIImage imageNamed:@"DoneUp.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"DoneDown.png"] forState:UIControlStateHighlighted];
}
[doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];
return doneButton;
}
- (void)doneButton:(id)sender {
NSLog(@"doneButton");
[self.view endEditing:TRUE];
}
回答3:
I kept playing with this a while and took a bunch of ideas from this and several other threads. I eventually made a subclass of UIViewController which would handle the numeric keyboard issue, but then I decided that would not be generic enough because I may need to inherit from UITableViewController and still implement this. So I refactored it made a helper class that does all the work and is fairly simple to implement. So here is what I ended up with. The .h file has the steps necessary to implement this in your UIViewController class where you want to use it.
The only thing I can't figure out is why I cannot get rid of this warning message "Attributes on method implementation and its declaration must match". I think it has something to do with the variable arguments list and NS_REQUIRES_NIL_TERMINATION
I hope that others find this code helpful and if anyone knows how to get rid of the warning message I'd love to find out.
Oh and I almost forgot you need to add the image files for the buttons. I downloaded them from some other thread a long time ago and forgot where, but they should not be hard to come by.
//
// NumericKeyboardHelper.h
//
// Created by Joseph Gagliardo on 7/6/12.
// Copyright (c) 2012 Joseph Gagliardo. All rights reserved.
//
#import <Foundation/Foundation.h>
/*
1. Import this header file
2. Add the NumericKeyboardHelperProtocol to the UIViewController<NumericKeyboardHelperProtocol>
3. Add a property to create this helper class
@property (strong, nonatomic) NumericKeyboardHelper *numericKeyboardHelper;
4. synthesize it and clean it up when done in the viewDidUnload
@synthesize numericKeyboardHelper=_numericKeyboardHelper;
[self setNumericKeyboardHelper:nil];
5. Insert the following line in the viewDidLoad of the controller
self.numericKeyboardHelper = [[NumericKeyboardHelper alloc] initWithObserver:self andSelector:@selector(numericDoneButtonPressed:) andFields: self.TextField1, self.TextField2, nil];
where self.TextField1, ... are the textField Outlets that have a numeric keyboard
6. Provide a numericDoneButtonPressed: method as required by the protocol to receive the message when the done button is pressed
The helper class does all the rest of the work
*/
@protocol NumericKeyboardHelperProtocol
- (void)numericDoneButtonPressed:(id)sender;
@end
@interface NumericKeyboardHelper : NSObject
@property (strong, nonatomic) UIButton *numericDoneButton;
@property (strong, nonatomic) NSArray *numericFields;
@property (weak, nonatomic) UIViewController *viewController;
- (void)showNumericKeyboard:(id)sender;
- (void)hideNumericKeyboard:(id)sender;
- (id) initWithObserver: (id) observer andSelector:(SEL)selector andFields:(UIControl *)argList, ... NS_REQUIRES_NIL_TERMINATION;
@end
//
// NumericKeyboardHelper.m
//
// Created by Joseph Gagliardo on 7/6/12.
// Copyright (c) 2012 Joseph Gagliardo. All rights reserved.
//
#import "NumericKeyboardHelper.h"
@implementation NumericKeyboardHelper
@synthesize numericDoneButton=_numericDoneButton;
@synthesize viewController=_viewController;
@synthesize numericFields=_numericFields;
- (id) initWithObserver: (id) observer andSelector:(SEL)selector andFields:(UIControl *)argList, ... NS_REQUIRES_NIL_TERMINATION
{
if (self = [super init])
{
[[NSNotificationCenter defaultCenter] addObserver:observer
selector:selector
name:@"numericDoneButtonPressed"
object:nil];
NSMutableArray *a = [[NSMutableArray alloc]init];
va_list args;
va_start(args, argList);
for (UIControl *arg = argList; arg != nil; arg = va_arg(args, UIControl*))
{
[a addObject:arg];
}
va_end(args);
self.numericFields = [NSArray arrayWithArray:a];
NSLog(@"Array count %i", [a count]);
self.viewController = observer;
[self setAllTextFields:self.viewController.view];
}
return self;
}
- (void) setAllTextFields: (UIView *) view
{
for (UIView *v in view.subviews)
{
if ([v isKindOfClass:[UITextField class]])
{
UITextField *t = (UITextField *)v;
if ([self.numericFields containsObject:v])
[t addTarget:self action:@selector(showNumericKeyboard:) forControlEvents:UIControlEventTouchDown];
else
[t addTarget:self action:@selector(hideNumericKeyboard:) forControlEvents:UIControlEventTouchDown];
}
else if ([v.subviews count] > 0)
{
[self setAllTextFields:v];
}
}
}
- (void)addNumericDoneButtonToKeyboard
{
if (self.numericDoneButton == nil)
{
self.numericDoneButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.numericDoneButton.frame = CGRectMake(0, 163, 106, 53);
self.numericDoneButton.adjustsImageWhenHighlighted = NO;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.0)
{
[self.numericDoneButton setImage:[UIImage imageNamed:@"DoneUp3.png"] forState:UIControlStateNormal];
[self.numericDoneButton setImage:[UIImage imageNamed:@"DoneDown3.png"] forState:UIControlStateHighlighted];
}
else
{
[self.numericDoneButton setImage:[UIImage imageNamed:@"DoneUp.png"] forState:UIControlStateNormal];
[self.numericDoneButton setImage:[UIImage imageNamed:@"DoneDown.png"] forState:UIControlStateHighlighted];
}
[self.numericDoneButton addTarget:self action:@selector(numericDoneButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
}
[[self keyboardView] addSubview:self.numericDoneButton];
}
- (void)showNumericKeyboard:(id)sender
{
[self addNumericDoneButtonToKeyboard];
self.numericDoneButton.hidden = NO;
}
- (void)hideNumericKeyboard:(id)sender
{
self.numericDoneButton.hidden = YES;
}
- (UIView *)keyboardView
{
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2 && [[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES) || [[keyboard description] hasPrefix:@"<UIKeyboard"] == YES)
return keyboard;
}
return nil;
}
- (void)numericDoneButtonPressed:(id)sender
{
for (UIControl *c in self.numericFields)
[c resignFirstResponder];
[[NSNotificationCenter defaultCenter]
postNotificationName:@"numericDoneButtonPressed"
object:sender ];
}
@end
来源:https://stackoverflow.com/questions/4360140/adding-done-button-to-only-number-pad-keyboard-on-iphone