UIKeyboard notifications don't post as expected on iOS17 beta2/beta1

Case 1: When a UITextView becomefirstresponder becomeFirstResponder for the first time after cold launch,it works fine

didReceiveKeyboardWillChangeFrameNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardWillShowNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardDidChangeFrameNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardDidShowNotification {{0, 508}, {390, 336}} 7

but notifications post twice afterwards

didReceiveKeyboardWillChangeFrameNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardWillShowNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardDidChangeFrameNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardDidShowNotification {{0, 508}, {390, 336}} 7

didReceiveKeyboardWillChangeFrameNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardWillShowNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardDidChangeFrameNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardDidShowNotification {{0, 508}, {390, 336}} 7

on iOS16,it works fine

2023-06-26 19:49:49.021938+0800 UITextView-demo[11835:1623447] didReceiveKeyboardWillChangeFrameNotification {{0, 508}, {390, 336}} 7
2023-06-26 19:49:49.022007+0800 UITextView-demo[11835:1623447] didReceiveKeyboardWillShowNotification {{0, 508}, {390, 336}} 7
2023-06-26 19:49:49.532870+0800 UITextView-demo[11835:1623447] didReceiveKeyboardDidChangeFrameNotification {{0, 508}, {390, 336}} 7
2023-06-26 19:49:49.535562+0800 UITextView-demo[11835:1623447] didReceiveKeyboardDidShowNotification {{0, 508}, {390, 336}} 7

Case 2: When a view is assigned to UITextView.input There are two weird behaviors:

  1. notifications post four times
  2. keyboard's height is 0 in the second notification
didReceiveKeyboardWillChangeFrameNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardWillShowNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardDidChangeFrameNotification {{0, 508}, {390, 336}} 7
didReceiveKeyboardDidShowNotification {{0, 508}, {390, 336}} 7

didReceiveKeyboardWillChangeFrameNotification {{0, 844}, {390, 0}} 7
didReceiveKeyboardWillShowNotification {{0, 844}, {390, 0}} 7
didReceiveKeyboardDidChangeFrameNotification {{0, 844}, {390, 0}} 7
didReceiveKeyboardDidShowNotification {{0, 844}, {390, 0}} 7

didReceiveKeyboardWillChangeFrameNotification {{0, 644}, {390, 200}} 7
didReceiveKeyboardWillShowNotification {{0, 644}, {390, 200}} 7
didReceiveKeyboardDidChangeFrameNotification {{0, 644}, {390, 200}} 7
didReceiveKeyboardDidShowNotification {{0, 644}, {390, 200}} 7

didReceiveKeyboardWillChangeFrameNotification {{0, 644}, {390, 200}} 7
didReceiveKeyboardWillShowNotification {{0, 644}, {390, 200}} 7
didReceiveKeyboardDidChangeFrameNotification {{0, 644}, {390, 200}} 7
didReceiveKeyboardDidShowNotification {{0, 644}, {390, 200}} 7

on iOS 16 it works fine

2023-06-26 19:41:54.991400+0800 UITextView-demo[11718:1618562] didReceiveKeyboardWillChangeFrameNotification {{0, 644}, {390, 200}} 7
2023-06-26 19:41:54.991513+0800 UITextView-demo[11718:1618562] didReceiveKeyboardWillShowNotification {{0, 644}, {390, 200}} 7
2023-06-26 19:41:54.991705+0800 UITextView-demo[11718:1618562] didReceiveKeyboardDidChangeFrameNotification {{0, 644}, {390, 200}} 7
2023-06-26 19:41:54.991928+0800 UITextView-demo[11718:1618562] didReceiveKeyboardDidShowNotification {{0, 644}, {390, 200}} 7

Code to reproduce:

#import "ViewController.h"

@interface ViewController () <UITextViewDelegate>

@property (nonatomic, strong) UITextView *textView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self registerForNotifications];
    
    {
        UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 100, 200, 100)];
        textView.backgroundColor = UIColor.whiteColor;
        textView.delegate = self;
        [self.view addSubview:textView];
        self.textView = textView;
    }
    
    {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        [button setTitle:@"resign" forState:UIControlStateNormal];
        [button sizeToFit];
        button.center = CGPointMake(50, 250);
        [button addTarget:self action:@selector(resign) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    }
    {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        [button setTitle:@"switch" forState:UIControlStateNormal];
        [button sizeToFit];
        button.center = CGPointMake(150, 250);
        [button addTarget:self action:@selector(switchV) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    }
    
    {
        UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 300, 200, 100)];
        textView.backgroundColor = UIColor.systemPinkColor;
        [self.view addSubview:textView];
    }
    
}

- (void)resign
{
    [self.textView resignFirstResponder];
}

- (void)switchV
{
    if (self.textView.inputView) {
        self.textView.inputView = nil;
        [self.textView reloadInputViews];
    } else {
        UIView *inputView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 200)];
        inputView.backgroundColor = UIColor.greenColor;
        self.textView.inputView = inputView;
        [self.textView reloadInputViews];
    }
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    NSLog(@"%@, %@", NSStringFromSelector(_cmd), NSStringFromRange(range));
    return YES;
}

- (void)registerForNotifications
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didReceiveKeyboardDidShowNotification:)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didReceiveKeyboardWillShowNotification:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didReceiveKeyboardWillChangeFrameNotification:)
                                                 name:UIKeyboardWillChangeFrameNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didReceiveKeyboardDidChangeFrameNotification:)
                                                 name:UIKeyboardDidChangeFrameNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didReceiveKeyboardWillHideNotification:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didReceiveKeyboardDidHideNotification:)
                                                 name:UIKeyboardDidHideNotification
                                               object:nil];
    
}

- (void)didReceiveKeyboardWillShowNotification:(NSNotification *)notification
{
    NSDictionary *userInfo = [notification userInfo];
    CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
    
    NSLog(@"didReceiveKeyboardWillShowNotification %@ %ld", NSStringFromCGRect(keyboardEndFrame), animationCurve);
}

- (void)didReceiveKeyboardDidShowNotification:(NSNotification *)notification
{
    NSDictionary *userInfo = [notification userInfo];
    CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
    
    NSLog(@"didReceiveKeyboardDidShowNotification %@ %ld", NSStringFromCGRect(keyboardEndFrame), animationCurve);
}

- (void)didReceiveKeyboardWillChangeFrameNotification:(NSNotification *)notification
{
    NSDictionary *userInfo = [notification userInfo];
    CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
    
    NSLog(@"didReceiveKeyboardWillChangeFrameNotification %@ %ld", NSStringFromCGRect(keyboardEndFrame), animationCurve);
}

- (void)didReceiveKeyboardDidChangeFrameNotification:(NSNotification *)notification
{
    NSDictionary *userInfo = [notification userInfo];
    CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
    
    NSLog(@"didReceiveKeyboardDidChangeFrameNotification %@ %ld", NSStringFromCGRect(keyboardEndFrame), animationCurve);
}

- (void)didReceiveKeyboardWillHideNotification:(NSNotification *)notification
{
    NSDictionary *userInfo = [notification userInfo];
    CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
    
    NSLog(@"didReceiveKeyboardWillHideNotification %@ %ld", NSStringFromCGRect(keyboardEndFrame), animationCurve);
}

- (void)didReceiveKeyboardDidHideNotification:(NSNotification *)notification
{
    NSDictionary *userInfo = [notification userInfo];
    CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
    
    NSLog(@"didReceiveKeyboardDidHideNotification %@ %ld", NSStringFromCGRect(keyboardEndFrame), animationCurve);
}


@end
UIKeyboard notifications don't post as expected on iOS17 beta2/beta1
 
 
Q