UIKeyboardWillChangeFrameNotification не срабатывает при нажатой кнопке диктовки (речь в текст) - PullRequest
0 голосов
/ 24 октября 2018

Я занимаюсь разработкой приложения с функцией чата, поэтому мое требование - отображать текстовое поле поверх клавиатуры.Поскольку требовалось не использовать представление прокрутки, я взял текстовое поле на UIView, и я использую уведомления keyborad (UIKeyboardWillChangeFrameNotification и UIKeyboardWillHideNotification), чтобы прокрутить текстовое поле соответственно.

Я сталкиваюсь с проблемой для устройства iPhone x, когда включен «интеллектуальный текст» и пользователь нажимает кнопку диктовки, между текстовым полем и клавиатурой будет разрыв, поскольку для диктовки не требуется «интеллектуальный текст».

Я пытаюсь определить высоту клавиатуры с помощью UIKeyboardWillChangeFrameNotification, но она не срабатывает при нажатии кнопки диктовки.

Добавление примера кода ниже.

@interface ViewController ()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraints;
@property (weak, nonatomic) IBOutlet UITextField *chatTextField;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardFrameChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keywindowResign:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:YES];
}

- (void)keyboardFrameChange:(NSNotification *)notification
{
    NSDictionary * userInfo = [notification userInfo];
    CGRect keyboardRect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    double duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    // Anchor the bottom of the message view to the top of the keyboard.
    [UIView animateWithDuration:duration animations:^{
        self.bottomConstraints.constant = 0 - CGRectGetHeight(keyboardRect) + self.view.safeAreaInsets.bottom;
        [self.view layoutIfNeeded];
    }];
}

- (void)keyboardWillHide:(NSNotification *)notification
{
    NSDictionary * userInfo = [notification userInfo];
    double duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    // Anchor the bottom of the message view to the bottom of the screen.
    [UIView animateWithDuration:duration animations:^{
        self.bottomConstraints.constant = 0;
        [self.view layoutIfNeeded];
    }];
}

- (void)keywindowResign:(NSNotification *)notification
{
    NSLog(@"%s","Key window resign");
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:true];
}

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

Пожалуйста, проверьтескриншоты, чтобы понять это больше.

enter image description here enter image description here

1 Ответ

0 голосов
/ 25 октября 2018

Я только что создал быстрый тестовый проект, и кажется, что при моем нажатии на кнопку диктовки на моем конце нормально проходит уведомление.Я могу только догадываться о том, что может пойти наперекосяк, так как вы вообще не включили свой код, но пара предположений:

  • Уведомление приходит, норасчеты, корректирующие высоту клавиатуры, неверны (возможно, не принимая во внимание safeAreaInsets.bottom?)
  • Вы удаляете себя в качестве наблюдателя уведомлений клавиатуры в какой-то момент до уведомления для рамки клавиатурыприходит изменение для диктовки.

Вот мой пример кода, который работал для меня:

#import "ViewController.h"

@interface ViewController ()
@property (strong, nullable) IBOutlet UITextField *tf;
@property (strong, nullable) IBOutlet UIView *redView;
@property (strong, nullable) IBOutlet NSLayoutConstraint *redViewBottomConstraint;
- (IBAction)resignActiveOnTF:(id)sender;
- (void)keyboardWillChangeFrame:(NSNotification *)notification;
- (void)keyboardWillHide:(NSNotification *)notification;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // put the redView off the bottom of the screen initially (include safe area insets on the bottom
    self.redViewBottomConstraint.constant = -(self.redView.frame.size.height + self.view.safeAreaInsets.bottom);
}

- (void)keyboardWillChangeFrame:(NSNotification *)notification {
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        CGFloat keyboardHeight = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
        [self.view layoutIfNeeded];
        // adjust the constraint by the keyboard height and account for the safe area insets on the bottom as well
        self.redViewBottomConstraint.constant = keyboardHeight - self.view.safeAreaInsets.bottom;
        [UIView animateWithDuration:0.4f animations:^{
            self.redView.alpha = 1.0f;
            [self.view layoutIfNeeded];
        }];
    }];
}

- (void)keyboardWillHide:(NSNotification *)notification {
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        [self.view layoutIfNeeded];
            self.redViewBottomConstraint.constant = -(self.redView.frame.size.height + self.view.safeAreaInsets.bottom);
        [UIView animateWithDuration:0.25f animations:^{
            self.redView.alpha = 0.0f;
            [self.view layoutIfNeeded];
        }];
    }];
}

- (IBAction)resignActiveOnTF:(id)sender {
    [self.tf resignFirstResponder];
}

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


@end

И пример его действия на симуляторе:

Keyboard_Notification_Example

Если ничего из этого не поможет вам, я настоятельно рекомендую воспроизвести это в очень простом примере и опубликовать свой код, чтобы другие могли помочь.

Редактировать:

Я скопировал ваш пример кода в новый контроллер представления, и мне кажется, что он работает нормально.Я сделал одну небольшую модификацию на моем конце для вычисления константы ограничения (мое нижнее ограничение - это нижняя часть представления, которое проходит через клавиатуру до нижней части безопасной области):

- (void)keyboardFrameChange:(NSNotification *)notification
{
    NSDictionary * userInfo = [notification userInfo];
    CGRect keyboardRect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    double duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    // Anchor the bottom of the message view to the top of the keyboard.
    [UIView animateWithDuration:duration animations:^{
        self.bottomConstraints.constant = (CGRectGetHeight(keyboardRect) - self.view.safeAreaInsets.bottom);
        [self.view layoutIfNeeded];
    }];
}

, хотя яЯ предполагаю, что у вас другое ограничение в вашей xib?

Я пытался запустить это непосредственно на iPhone 6s, и это работает там же.У меня нет физического устройства iPhone X, на котором можно было бы его протестировать.

...