0

내 시스템의 한 가지 목표는 일반 시스템 키보드와 함께 여러 개의 사용자 정의 입력보기 (펜촉에서)를 관리하는 것입니다. 둘 중 하나가 항상 존재합니다. (예제 코드에서는 단일 키보드 + 시스템 키보드 만 관리합니다).becomeFirstResponder가 UIKeyboardDidHideNotification을 트리거합니다.

키보드를 교체 할 때 시스템 키보드에서 볼 수있는 슬라이드 인/슬라이드 아웃 효과를 유지하려고합니다. 사용자 정의 키보드와 시스템 키보드 모두 슬라이딩 애니메이션을 얻으려면 텍스트 필드에서 resignFirstResponder를 호출하고 키보드가 숨겨 질 때까지 기다리십시오. 그런 다음 becomeFirstResponder를 실행하여 새 키보드를 가져옵니다. UIKeyboardDidHideNotification을 트리거로 사용하여 becomeFirstResponder를 시작하고 새 키보드를로드합니다.

내가보기에 문제는 UIKeyboardDidHideNotification이 resignFirstResponder (예상대로)를 실행할 때와 becomeFirstResponder가 실행될 때 한 번 두 번 실행된다는 것입니다. 나는 두 번째 알림을 감지 할 수있는 상태를 넣을 수 있다고 생각하지만, whyFirstResponder가 첫 번째 알림을 발생시키는 이유는 무엇입니까?

#import "DemoViewController.h" 

@interface DemoViewController() 
@property (strong, nonatomic) IBOutlet UITextField *dummyTextField; 
@end 

@implementation DemoViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [[UITextField appearance] setKeyboardAppearance:UIKeyboardAppearanceDark]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil]; 

    [self showNormalKeyboard]; 
    [_dummyTextField becomeFirstResponder]; 
} 

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

-(void)keyboardDidHide:(NSNotification*) notification { 
    NSLog(@"Keyboard hidden: %@", notification); 
    // Executing this next line causes the notification to fire again 
    [_dummyTextField becomeFirstResponder]; 
} 

-(void)showAlternateKeyboard{ 
    _dummyTextField.inputView = [[[NSBundle mainBundle] loadNibNamed:@"AlternateKeyboardView" owner:self options:nil] lastObject]; 
    [_dummyTextField resignFirstResponder]; 
} 

-(void)showNormalKeyboard{ 
    _dummyTextField.inputView = nil; 
    [_dummyTextField resignFirstResponder]; 
} 

// This is a button on the DemoViewController screen 
// that is always present. 
- (IBAction)mainButtonPressed:(UIButton *)sender { 
    NSLog(@"Main Screen Button Pressed!"); 
} 

// This is a button from the Custom Input View xib 
// but hardwired directly into here 
- (IBAction)alternateKeyboardButtonPressed:(UIButton *)sender { 
    NSLog(@"Alternate Keyboard Button Pressed!"); 
} 

// This is a UISwitch on the DemoViewController storyboard 
// that selects between the custom keyboard and the regular 
// system keyboard 
- (IBAction)keyboardSelectChanged:(UISwitch *)sender { 
    if (sender.on){ 
     [self showAlternateKeyboard]; 
    } else { 
     [self showNormalKeyboard]; 
    } 
} 

@end 

답변

2

내 생각 엔 이전 필드가 완전히 첫 번째로 반응을 사임 완료하기 전에 becomeFirstResponder를 호출하는 것입니다. 도움이된다면 그냥보고, 약간의 지연 성능을 추가하려고 : 일

-(void)keyboardDidHide:(NSNotification*) notification { 
    NSLog(@"Keyboard hidden: %@", notification); 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [_dummyTextField becomeFirstResponder]; 
    }; 
} 
+0

합니다. resignFirstResponder가 완료되었음을 동 기적으로 확신 할 수있는 방법이 있는지 궁금합니다. –

+0

실제로 우리가 여기에서하고있는 것과 정확히 일치합니다. 우리는 진행하기 전에 상황을 진정 시키도록 runloop의 한 바퀴 돌기 만하고 있습니다. 그것에 대해 실제로 "비동기"는 없습니다. 모든 코드가 실행을 마친 즉시 다시 시작하는 것은 최소한의 일시 중지입니다. – matt

0
@interface MainViewController : UIViewController 

@property (nonatomic, retain) IBOutlet UITextField *textField; 
@property (nonatomic, retain) IBOutlet UISwitch *keyboardSwitch; 
@property (nonatomic, retain) IBOutlet UISwitch *textFieldSwitch; 


- (IBAction)toggleKeyboardVisibility; 

@end 


#import "MainViewController.h" 

@implementation MainViewController 
@synthesize textField, keyboardSwitch, textFieldSwitch; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
} 

/** 
* Show keyboard as soon as view appears 
* 
*/ 
- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self.textField becomeFirstResponder]; 
} 

/** 
* Modify the hidden property of our text field 
* 
*/ 
- (IBAction)toggleTextFieldVisibility 
{ 
    if (self.textFieldSwitch.on) 
     self.textField.hidden = NO; 
    else 
     self.textField.hidden = YES; 
} 

/** 
* Change the first responder status of the keyboard 
* 
*/ 
- (IBAction)toggleKeyboardVisibility 
{ 
    if (self.keyboardSwitch.on) 
     [self.textField becomeFirstResponder]; 
    else 
     [self.textField resignFirstResponder]; 
} 

@end 
관련 문제