Добавление кнопки «Готово» только на клавиатуру с цифровой клавиатурой на iPhone

Я успешно добавляю кнопку «Готово» на свою цифровую клавиатуру с помощью этого удобного кода ниже. Но у меня есть кнопка электронной почты, запускающая MFMailComposeViewController. Как убедиться, что кнопка «Готово» не отображается на клавиатуре электронной почты?

//
//  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

Я пытаюсь расширить UIViewController, чтобы он делал это автоматически, когда я импортирую этот подкласс, поэтому логический флаг в моем приложении, вероятно, не будет работать.


person Bryan    schedule 05.12.2010    source источник


Ответы (3)


Для iOS 3.2+ вам все равно больше не следует использовать этот хак. Вместо этого назначьте настраиваемое представление свойству inputAccessoryView элемента управления.

person Ole Begemann    schedule 05.12.2010
comment
Можете ли вы уточнить пример кода? Где мне использовать inputAccessoryView? - person Bryan; 05.12.2010
comment
Посмотрите inputAccessoryView в документации. Вы назначаете настраиваемое представление для myTextField.inputAccessoryView = ..., и оно автоматически появляется, когда это текстовое поле становится первым респондентом. - person Ole Begemann; 05.12.2010
comment
Мне не удалось разместить кнопку. Он остался вверху и в центре клавиатуры, но работает. - person Bryan; 05.12.2010
comment
Затем поместите его в настраиваемый вид, занимающий всю ширину экрана (создавая вид панели инструментов). - person Ole Begemann; 05.12.2010
comment
Спасибо Оле. Вот что я сделал. - person Bryan; 06.12.2010
comment
Для будущих посетителей .. Используйте этот подход. - person Bhavin; 21.01.2015

Я продолжал играть с этим некоторое время и взял кучу идей из этой и нескольких других тем. В конце концов я создал подкласс UIViewController, который будет обрабатывать проблему с числовой клавиатурой, но затем я решил, что это будет недостаточно универсальным, потому что мне может потребоваться наследовать от UITableViewController и по-прежнему реализовывать это. Поэтому я реорганизовал его, и создал вспомогательный класс, который выполняет всю работу и довольно прост в реализации. Итак, вот что у меня получилось. В файле .h есть шаги, необходимые для реализации этого в вашем классе UIViewController, где вы хотите его использовать.

Единственное, чего я не могу понять, это почему я не могу избавиться от этого предупреждающего сообщения «Атрибуты реализации метода и его объявление должны совпадать». Я думаю, это как-то связано со списком переменных аргументов и NS_REQUIRES_NIL_TERMINATION

Я надеюсь, что другие сочтут этот код полезным, и если кто-нибудь знает, как избавиться от предупреждающего сообщения, я хотел бы узнать.

Да, и я почти забыл, что вам нужно добавить файлы изображений для кнопок. Я скачал их из какой-то другой ветки давным-давно и забыл где, но их нетрудно найти.

//
//  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
person Joseph Gagliardo    schedule 06.07.2012
comment
Какие темы? Пожалуйста, укажите ссылку на другие темы! Это лень в том, что вы сказали, Я скачал их из какой-то другой ветки давным-давно и забыл где, но их будет нетрудно найти. -1 от меня! - person t0mm13b; 10.10.2012

person    schedule
comment
Привет ... как вы получили готовые изображения? Раньше у меня они были в моем приложении, и я потерял ссылки. Вы можете направить меня на сайт? - person CodeGuy; 12.02.2012
comment
Этот ответ вдохновил меня на создание более надежной версии, которая хорошо работает даже с двумя разными типами клавиатур в одном родительском представлении Horsehoe7.wordpress.com/2012/08/17/ - person horseshoe7; 04.10.2012