Adding Done Button to Only Number Pad Keyboard on iPhone

孤人 提交于 2020-01-21 05:25:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!