iOS에서 숫자 키패드 키보드에 '완료'버튼을 추가하는 방법


84

따라서 숫자 패드 키보드에는 기본적으로 '완료'또는 '다음'버튼이 제공되지 않으므로 하나를 추가하고 싶습니다. iOS 6 이하에는 키보드에 버튼을 추가하는 몇 가지 트릭이 있었지만 iOS 7에서는 작동하지 않는 것 같습니다.

먼저 알림을 표시하는 키보드를 구독합니다.

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

그런 다음 키보드가 나타나면 버튼을 추가하려고합니다.

- (void)keyboardWillShow:(NSNotification *)note 
{
    // create custom button
    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeSystem];
    doneButton.frame = CGRectMake(0, 50, 106, 53);
    doneButton.adjustsImageWhenHighlighted = NO;
    [doneButton setTitle:@"Done" forState:UIControlStateNormal];
    [doneButton addTarget:self action:@selector(dismissKeyboard) 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 view found; add the custom button to it
        if([[keyboard description] hasPrefix:@"UIKeyboard"] == YES)
        [keyboard addSubview:doneButton];
    }
}

그러나 for 루프는 하위 뷰를 찾지 못하기 때문에 실행되지 않습니다. 어떤 제안? iOS7에 대한 솔루션을 찾을 수 없으므로이 작업을 수행해야하는 다른 방법이 있습니까?

편집 : 툴바 녀석에 대한 모든 제안에 감사하지만 나는 공간이 부족하기 때문에 그 경로를 따르지 않을 것입니다 (그리고 그것은 추악합니다).


이 게시물을 사용해 보셨습니까? neoos.ch/blog/...
아닐

@Anil UIKeyboard를 사용자 정의하는 방법은 애플에서 금지합니다.
βhargavḯ 2013

UIKeyboardDidShowNotification으로 확인하십시오.
Praveen Matanam 2013


2
도구 모음을 추가하고 싶지 않고 바로 키보드에 버튼을 배치하고 싶습니다.
George McKibbin 2013

답변:


26

이것은 iOS7 숫자 키패드에서 완료 버튼을 투영하는 간단한 방법입니다. UITextField의 아래 델리게이트 메서드에서 키보드 쇼에 대한 알림을 추가합니다.

-(void)textFieldDidBeginEditing:(UITextField *)textField {

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];
}

이제 keyboardWillShow아래와 같이 방법 을 구현하십시오 . 여기서 우리는 iOS7에 대한 특별한주의가 필요합니다.

- (void)keyboardWillShow:(NSNotification *)note {
// create custom button
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 163, 106, 53);
doneButton.adjustsImageWhenHighlighted = NO;
[doneButton setImage:[UIImage imageNamed:@"doneButtonNormal.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"doneButtonPressed.png"] forState:UIControlStateHighlighted];
[doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
    dispatch_async(dispatch_get_main_queue(), ^{
        UIView *keyboardView = [[[[[UIApplication sharedApplication] windows] lastObject] subviews] firstObject];
        [doneButton setFrame:CGRectMake(0, keyboardView.frame.size.height - 53, 106, 53)];
        [keyboardView addSubview:doneButton];
        [keyboardView bringSubviewToFront:doneButton];

        [UIView animateWithDuration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]-.02
                              delay:.0
                            options:[[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]
                         animations:^{
                             self.view.frame = CGRectOffset(self.view.frame, 0, 0);
                         } completion:nil];
    });
}else {
    // locate keyboard view
    dispatch_async(dispatch_get_main_queue(), ^{
        UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
        UIView* keyboard;
        for(int i=0; i<[tempWindow.subviews count]; i++) {
            keyboard = [tempWindow.subviews objectAtIndex:i];
            // keyboard view found; add the custom button to it
            if([[keyboard description] hasPrefix:@"UIKeyboard"] == YES)
                [keyboard addSubview:doneButton];
        }
    });
  }
}

이제이 매크로를 적절한 헤더에 추가하여 SYSTEM_VERSION을 감지하십시오.

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)


1
고마워, 이것이 내가 원했던 것입니다. :) 불행히도 이미 화면에 키보드가 있고 숫자 패드 키보드가 필요한 필드로 전환하면 keyBoardWillShow가 호출되지 않습니다. 그러나 감사합니다, 올바른 방향으로 한 걸음 하하.
George McKibbin 2013

SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO NSFoundationVersionNumber> NSFoundationVersionNumber_iOS_6_0이 아닌 이유는 무엇입니까? 그리고 나는 그것을 테스트, NSFoundationVersionNumber_iOS_5_0 더 낫다
govo

dispatch_async는 여기서 키보드를 해킹하는 가장 안정적인 방법이 아닙니다. :(
pronebird

7
iOS8에서이 완료 버튼은 키보드 해제 후 숨겨지지 않습니다.
Hemant Chittora 2014 년

2
이 대답은 영리하지만 깨질 수밖에 없었다.
SwiftArchitect

187

훨씬 안전한 접근 방식은 UIToolBarwith DoneButton을 inputAccessoryView.


샘플 코드 :

UIToolbar *keyboardDoneButtonView = [[UIToolbar alloc] init];
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
                                                               style:UIBarButtonItemStyleBordered target:self
                                                              action:@selector(doneClicked:)];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
txtField.inputAccessoryView = keyboardDoneButtonView;

귀하의 -doneClicked방법은 다음과 같아야합니다 :

- (IBAction)doneClicked:(id)sender
{
    NSLog(@"Done Clicked.");
    [self.view endEditing:YES];
}

샘플 코드 Swift :

let keyboardDoneButtonView = UIToolbar.init()
keyboardDoneButtonView.sizeToFit()
let doneButton = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.Done, 
                                                   target: self, 
                                                   action: Selector("doneClicked:")))    

keyboardDoneButtonView.items = [doneButton]
textFieldInput.inputAccessoryView = keyboardDoneButtonView

귀하의 -doneClicked방법은 다음과 같아야합니다 :

func doneClicked(sender: AnyObject) {
  self.view.endEditing(true)
}

이 일을 끝내야 할 수도 있습니다. 나는 그것이 얼마나 많은 공간을 차지하는지 정말로 좋아하지 않습니다.
George McKibbin 2013

3
@GeorgeMcKibbin : 입력하는 동안에 만 해당 공간을 차지하므로 공백은 여기서 문제가되지 않아야합니다. 또한 나에 따르면이 접근 방식은 일반적으로 Apple이 좋아하지 않는 키보드를 엉망으로 만드는 것보다 훨씬 낫습니다.
Bhavin 2013

이렇게하면 화면 맨 아래에 도구 모음 만 표시되고 키보드가 더 이상 나타나지 않습니다. 생각?
Chris

좋은 대답은, 하나의 재미있는 이야기, arrayWithObjects는 unspokenly 리터럴에 찬성되지 않습니다 : [NSArray를 arrayWithObjects : doneButton, 무] => @ [doneButton]
오스틴

1
iOS 8.0 UIBarButtonItemStyleBordered에서 더 이상 사용되지 UIBarButtonItemStyleDone않거나UIBarButtonItemStylePlain
Nazir

131

더 쉬운 방법 :

Swift 3.0 이상 :

func addDoneButton() {
    let keyboardToolbar = UIToolbar()
    keyboardToolbar.sizeToFit()
    let flexBarButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
        target: nil, action: nil)
    let doneBarButton = UIBarButtonItem(barButtonSystemItem: .done,
        target: view, action: #selector(UIView.endEditing(_:)))
    keyboardToolbar.items = [flexBarButton, doneBarButton]
    textField.inputAccessoryView = keyboardToolbar
}

Swift 2.3 이하 :

func addDoneButton() {
    let keyboardToolbar = UIToolbar()
    keyboardToolbar.sizeToFit()
    let flexBarButton = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace,
        target: nil, action: nil)
    let doneBarButton = UIBarButtonItem(barButtonSystemItem: .Done,
        target: view, action: #selector(UIView.endEditing(_:)))
    keyboardToolbar.items = [flexBarButton, doneBarButton]
    textField.inputAccessoryView = keyboardToolbar
}

목표 C :

- (void)addDoneButton {
    UIToolbar* keyboardToolbar = [[UIToolbar alloc] init];
    [keyboardToolbar sizeToFit];
    UIBarButtonItem *flexBarButton = [[UIBarButtonItem alloc]
    initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
    target:nil action:nil];
    UIBarButtonItem *doneBarButton = [[UIBarButtonItem alloc]
    initWithBarButtonSystemItem:UIBarButtonSystemItemDone
    target:self.view action:@selector(endEditing:)];
    keyboardToolbar.items = @[flexBarButton, doneBarButton];
    self.textField.inputAccessoryView = keyboardToolbar;
}

편집하다:

이미 도구 모음이 기본 제공되는 DCKit 이라는 유용한 라이브러리를 만들었습니다 .

iOS에서 키보드 위의 도구 모음 완료 (DCKit 라이브러리 사용)

또한 다른 많은 멋진 기능이 있습니다.


1
나에게는 1 년 전 Bhavin의 답변에 새로운 답변으로 플렉스 바 버튼을 추가하여 누군가가 왜 투표했는지 알 수 있습니다. 여기서도 뭔가 놓친 건가요?
Mark McCorkle 2014-08-07

2
예, 사용하지 않고 대신 initWithTitle:@"Done"사용 initWithBarButtonSystemItem:UIBarButtonSystemItemDone합니다. 그러면 표준 Apple의 완료 바 버튼이 반환됩니다. 또한 이미 현지화 될 예정입니다
Andrey Gordeev 2014-08-07

3
이것은 이전의 정답 IMO에 대한 개선 (코멘트)으로 추가되거나 하향 투표를 예상해야합니다. 새로운 답변은 기존 질문에 대한 개선이 아니라 원래 질문에 대한 다른 접근 방식을 포함해야합니다. 그럼에도 불구하고 개선해 주셔서 감사합니다. ;-)
Mark McCorkle 2014 년

4
아니요, 그렇게 생각하지 않습니다. 댓글 : 코드 작성에 사용되지 않는 것으로
안드레이 고르 디프을

13

번역해야했기 때문에 Swift 버전으로 위의 답변을 작성하면됩니다.

   @IBOutlet weak var numberTextField: UITextField!

    override func viewDidLoad() {
        addDoneButtonTo(numberTextField)
    }

    // MARK: Done for numberTextField

    private func addDoneButtonTo(textField: UITextField) {
        let flexBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
        let doneBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action: "didTapDone:")
        let keyboardToolbar = UIToolbar()
        keyboardToolbar.sizeToFit()
        keyboardToolbar.items = [flexBarButton, doneBarButton]
        textField.inputAccessoryView = keyboardToolbar
    }

    func didTapDone(sender: AnyObject?) {
        numberTextField.endEditing(true)
    }

3

당신이 사용할 수있는

myTextField.inputAccessoryView = _inputView;

입력 액세서리보기는 키보드 위에 항상 표시되고 [textfield resignFirstResponder]

done입력 뷰 위에 놓고 텍스트 필드의 resignfirst 응답자를 수행합니다.



2
enter code here

1. register the controller to the notification

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // Keyboard events
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardWillHideNotification
                                           object:nil];
}

2. don't forget to remove the controller from the notification centre

-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [self.view endEditing:YES];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

3. implement keyboard notification handlers

- (void)keyboardWillShow:(NSNotification *)notification {

// create custom button
    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
    doneButton.frame = CGRectMake(0, 107, 106, 53);
    [doneButton setTitle:@"Done" forState:UIControlStateNormal];
    [doneButton addTarget:self  action:@selector(doneButton:)forControlEvents:UIControlEventTouchUpInside];

// save the reference to the button in order to use it in keyboardWillHide method
   self.donekeyBoardBtn = doneButton;

// to my mind no need to search for subviews
   UIWindow *windowContainigKeyboard = [[[UIApplication sharedApplication] windows]  lastObject];
   [windowContainigKeyboard addSubview:self.donekeyBoardBtn];
   self.donekeyBoardBtn.frame = CGRectMake(0., CGRectGetHeight(w.frame) -  CGRectGetHeight(self.donekeyBoardBtn.frame), CGRectGetWidth(self.donekeyBoardBtn.frame), CGRectGetHeight(self.donekeyBoardBtn.frame));
}

- (void)keyboardWillHide:(NSNotification *)notification {

    [self.donekeyBoardBtn removeFromSuperview];
}

4. implement done button action

- (void)doneButton:(id)sender{
   // add needed implementation
      [self.view endEditing:YES]; 
}

나는 당신의 대답을 내가해야 할 일과 매우 유사하게 구현했습니다. 감사. 그러나 키보드가 표시 될 때 버튼은 애니메이션 개체로 제공되지 않습니다.
Arpit B Parekh

1

iPad는 "숫자"패드에 리턴 키를 구현하므로 휴대 전화 또는 iPad를 사용하는지 감지해야합니다.


0

키보드보기는 hasPrefix : @ "UIKeyboard"를 찾을 수 있습니다. 단추는 하위보기로 추가 할 수 없습니다. 내 솔루션은 다음과 같습니다. 여기에 링크 설명 입력

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.