显示键盘时,自定义 UIView 正在向上推部分内容

Posted

技术标签:

【中文标题】显示键盘时,自定义 UIView 正在向上推部分内容【英文标题】:Custom UIView is Pushing Partial Contents Up When the Keyboard is Shown 【发布时间】:2018-03-08 18:51:34 【问题描述】:

我已经构建了一个自定义 UIView,并将其添加到 UIViewController。

我希望我的自定义 UIView 向上移动以显示键盘隐藏的任何文本字段。但是,它似乎只是将 UIView 的其他元素向上推。

我做错了什么? 没有键盘:

注意当显示键盘时日期和公司名称是如何被推到UITextFields 后面的

LogInViewController.m

@interface LogInViewController () <UITextFieldDelegate> 
    LoginView * loginView;

@property (nonatomic, assign) CGRect   keyboardFrame;
@end

- (void)viewDidLoad 
    [super viewDidLoad];

    loginView = [[LoginView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:loginView];

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self selector:@selector(handleKeyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    [nc addObserver:self selector:@selector(handleKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];


- (void)handleKeyboardDidShow:(NSNotification *)notification 
    NSTimeInterval animationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];

    _keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    _keyboardFrame = [self.view convertRect:_keyboardFrame fromView:self.view.window];

    [UIView animateWithDuration:animationDuration animations:^
        CGRect frm = loginView.frame;
        frm.size.height = CGRectGetMinY(_keyboardFrame);
        loginView.frame = frm;
    ];


- (void)handleKeyboardWillHide:(NSNotification *)notification 
    NSTimeInterval animationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];

    [UIView animateWithDuration:animationDuration animations:^
        CGRect frm = loginView.frame;
        frm.size.height = CGRectGetMaxY(self.view.bounds);
        loginView.frame = frm;
    ];

LoginView.h

@interface LoginView : UIView
@property (strong, nonatomic) IBOutlet UIView *contentView;
@property (weak, nonatomic) IBOutlet UITextField *txtUsername;
@property (weak, nonatomic) IBOutlet UITextField *txtPassword;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *indicator;
@property (weak, nonatomic) IBOutlet UIButton *btnSignin;
@property (weak, nonatomic) IBOutlet UILabel *lblVersion;
@property (weak, nonatomic) IBOutlet UILabel *lblMessageArea;
@end

LoginView.m

@implementation LoginView
- (instancetype) initWithFrame:(CGRect)frame 
    self = [super initWithFrame:frame];
    if(self)

        [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
        [self addSubview:self.contentView];
        self.contentView.frame = self.bounds;
    
    return self;

@end

【问题讨论】:

使用 IQKeyboard 库 【参考方案1】:

你覆盖了_keboardFrame,所以第一个赋值是没用的。

    _keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    _keyboardFrame = [self.view convertRect:_keyboardFrame fromView:self.view.window];

我建议使用 UIKeyboardWillShowNotification 以获得更一致的动画:

// for your code, I prefer case 1, to shift up the entire view. Anyway, if you want, you can use the second option that I've commented. But the best option is to use constraints, then update that constraint
- (void)keyboardWillShow:(NSNotification *)notification 
    NSTimeInterval animationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];

    CGFloat keyboardHeight = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;

    [UIView animateWithDuration:animationDuration animations:^
        CGRect frm = loginView.frame;
        // 1. move up the view
        frm.origin.y = -keyboardHeight;
        // 2. change the height
        //frm.size.height = self.view.bounds.size.height - keyboardHeight;
        loginView.frame = frm;
    ];


- (void)keyboardWillHide:(NSNotification *)notification 
    NSTimeInterval animationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
        [UIView animateWithDuration:animationDuration animations:^
            loginView.frame = self.view.bounds;
        ];

这适合你吗?

【讨论】:

以上是关于显示键盘时,自定义 UIView 正在向上推部分内容的主要内容,如果未能解决你的问题,请参考以下文章

出现键盘时无法上移自定义 UIView

使用小键盘时,底部工具栏如何始终向上推?

iOS 8 自定义键盘自动布局键

React Native:Android 软键盘将 View 向上推

出现键盘时向上移动 UIView

使用 phonegap 防止键盘在 iOS 应用程序中向上推 webview