0

我的應用程序的目標之一是管理多個自定義輸入視圖(從筆尖)以及常規系統鍵盤。其中一個或另一個將始終存在。 (在示例代碼中,我只管理單個筆尖+系統鍵盤)。becomeFirstResponder觸發UIKeyboardDidHideNotification

當換掉鍵盤時,我想保留您使用系統鍵盤看到的滑入/滑出效果。爲了獲得自定義鍵盤以及系統鍵盤的滑動動畫,我從文本字段resignFirstResponder並等待,直到隱藏鍵盤。然後我執行一個becomeFirstResponder來引入新的鍵盤。我使用UIKeyboardDidHideNotification作爲觸發器來觸發becomeFirstResponder並加載新鍵盤。

我看到的問題是,UIKeyboardDidHideNotification觸發兩次......一次執行resignFirstResponder(如預期的)並再次執行becomeFirstResponder時。我懷疑我可以通過某種狀態來檢測第二個通知,但是我想了解,爲什麼成爲FirstResponder會導致它首先被觸發?

#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

這實際上就是我們在這裏所做的。在繼續之前,我們只是輪迴旋轉一圈,讓事情安頓下來。實際上沒有任何關於它的「異步」。這是一個最小的暫停,只要所有代碼完成執行,就會立即恢復。 – 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 
相關問題