Obj-C - NSNotification执行两次?

时间:2018-02-06 08:40:37

标签: ios objective-c

出于某种原因,UIKeyboardWillHideNotification正在我的下面代码中执行两次 - 我还没有找到原因的线索。我知道这是因为我的NSLog("已关闭!")在我的控制台中出现两次。我错过了一些明显的东西(不,我不会在我的代码中第二次粘贴UIKeyboardWillHideNotification)。

-(void)viewDidLoad {

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

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

}

- (void)handleKeyboard:(NSNotification*)aNotification{
    NSDictionary* info = [aNotification userInfo];
    NSValue* value = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval duration = 3;
    [value getValue:&duration];

    if (aNotification.name == UIKeyboardWillShowNotification) {

        self.upView.frame = CGRectOffset(self.upView.frame, 0, -self.keyboardHeight); self.tableView.frame = CGRectOffset(self.tableView.frame, 0, -self.keyboardHeight);

        [self moveCustomView:YES duration:duration];
    }

    if (aNotification.name == UIKeyboardWillHideNotification) {
        /** KEYBOARD HIDE **/


        self.upView.frame = CGRectOffset(self.upView.frame, 0, self.keyboardHeight); self.tableView.frame = CGRectOffset(self.tableView.frame, 0, self.keyboardHeight);

        [self moveCustomView:NO duration:duration];
        NSLog(@"CLOSED!");
    }


}

4 个答案:

答案 0 :(得分:0)

确保删除viewDidDisappear中的观察者,因为视图控制器可能由于某种原因而未重新分配,并且viewDidLoad中的代码在观察者添加两次时执行两次

//目标c

 - (void)viewWillDisappear:(BOOL)paramAnimated{
   [super viewWillDisappear:paramAnimated];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter]  removeObserver:self name:UIKeyboardWillHideNotification object:nil];

}

// Swift

 override func viewDidDisappear(_ animated: Bool)
{


    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardDidShow, object: nil)

    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)


}

答案 1 :(得分:0)

请务必从dealloc方法中删除观察者。如果您不删除它并且其内存未释放,它将侦听其他页面上的键盘行为。此外,您不应将同一通知两次添加到同一观察者。

答案 2 :(得分:0)

而不是使用相同的方法隐藏和显示通知。您可以使用两种不同的方法。

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification object:nil];

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

现在,更改框架您可以使用以下代码

NSDictionary* info = [aNotification userInfo];
   CGSize *kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
self.tableView.frame = CGRectOffset(self.tableView.frame, 0, -kbSize.height); 

答案 3 :(得分:0)

请尝试这样:

我做了什么:

•已将订阅移至viewWillAppear

•在viewWillDisappear

中添加了“取消订阅”

•在dealloc中添加了“取消订阅”(与您的问题无关,但这仍然是正确的方法)

•在您的处理程序中使用isEqual替换==(也与您的问题无关,最有可能)。

那里可能存在一些错别字。对不起,如果是这样的话。

-(void)viewWillAppear {
    [super viewWillAppear];

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

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


-(void)viewDidLoad {
    [super viewDidLoad];
    //Leaving this method here just to point out that everything was moved to viewWillAppear
}

- (void)handleKeyboard:(NSNotification*)aNotification{
    NSDictionary* info = [aNotification userInfo];
    NSValue* value = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval duration = 3;
    [value getValue:&duration];

    if ([aNotification.name isEqual: UIKeyboardWillShowNotification]) {
        self.upView.frame = CGRectOffset(self.upView.frame, 0, -self.keyboardHeight);
        self.tableView.frame = CGRectOffset(self.tableView.frame, 0, -self.keyboardHeight);
        [self moveCustomView:YES duration:duration];
    }

    if ([aNotification.name isEqual: UIKeyboardWillHideNotification]) {
        /** KEYBOARD HIDE **/
        self.upView.frame = CGRectOffset(self.upView.frame, 0, self.keyboardHeight); 
        self.tableView.frame = CGRectOffset(self.tableView.frame, 0, self.keyboardHeight);

        [self moveCustomView:NO duration:duration];
        NSLog(@"CLOSED!");
    }
}

-(void)unsubscribe {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

-(void)viewWillDisappear {
    [super viewWillDisappear];
    [self unsubscribe];
}

-(void)dealloc {
    [self unsubscribe];
}