Move UIView up when the keyboard appears in iOS

后端 未结 18 1769
再見小時候
再見小時候 2020-11-28 20:38

I have a UIView, it is not inside UIScrollView. I would like to move up my View when the keyboard appears. Before I tried to use this solution: How can I make a UITextField

相关标签:
18条回答
  • 2020-11-28 20:45

    i just created a lightweight keyboard handler to follow keyboard frame.

    Usage:

     self.keyboardHandler = [EDKeyboardHandler new];
    
      [self.keyboardHandler listenWithBlock:^(KeyboardInfo *model)
      {
        //adjust view positions according to keyboard position here
      }];
    

    and the KeyboardInfo model has the following properties:

    typedef enum : NSUInteger {
        KeyboardStatusDidShow,
        KeyboardStatusWillShow,
        KeyboardStatusDidHide,
        KeyboardStatusWillHide,
    } KeyboardStatus;
    
    @interface KeyboardInfo:NSObject
    
    @property (nonatomic,readonly) NSTimeInterval animationDuration;
    @property (nonatomic,readonly) CGRect keyboardFrame;
    @property (nonatomic,readonly) NSInteger animationCurve;
    @property (nonatomic,readonly) KeyboardStatus status;
    
    @end
    

    check GitHub project for details and cocoaPods integration.

    0 讨论(0)
  • 2020-11-28 20:46

    It can be done easily & automatically if that textfield is in a table's cell (even when the table.scrollable = NO).

    NOTE that: the position and size of the table must be reasonable. e.g:

    • if the y position of table is 100 counted from the view's bottom, then the 300 height keyboard will overlap the whole table.
    • if table's height = 10, and the textfield in it must be scrolled up 100 when keyboard appears in order to be visible, then that textfield will be out of the table's bound.
    0 讨论(0)
  • 2020-11-28 20:47
    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    }
    
    #pragma mark - keyboard movements
    - (void)keyboardWillShow:(NSNotification *)notification
    {
        CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    
        [UIView animateWithDuration:0.3 animations:^{
            CGRect f = self.view.frame;
            f.origin.y = -keyboardSize.height;
            self.view.frame = f;
        }];
    }
    
    -(void)keyboardWillHide:(NSNotification *)notification
    {
        [UIView animateWithDuration:0.3 animations:^{
            CGRect f = self.view.frame;
            f.origin.y = 0.0f;
            self.view.frame = f;
        }];
    }
    
    0 讨论(0)
  • 2020-11-28 20:47

    Just in case someone is looking for solution in Swift, throw this in your code:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: .UIKeyboardWillHide, object: nil)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
    }
    
    
    @objc func keyboardWillShow(notification: Notification) {
        if let userInfo = notification.userInfo {
            if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
                UIView.animate(withDuration: 0.3) {
                    var alteredFrame = self.view.frame
                    alteredFrame.origin.y = -keyboardSize.height
                    self.view.frame = alteredFrame
                }
            }
        }
    }
    
    @objc func keyboardWillHide(notification: Notification) {
        UIView.animate(withDuration: 0.3) {
            var alteredFrame = self.view.frame
            alteredFrame.origin.y = 0.0
            self.view.frame = alteredFrame
        }
    }
    
    0 讨论(0)
  • 2020-11-28 20:47

    Declare a delegate, assign your text field to the delegate and then include these methods.

    Assuming you have a login form with email and password text fields, this code will fit perfectly:

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    
        [self.emailTextField resignFirstResponder];
        [self.passwordTextField resignFirstResponder];
    
    }
    
    - (BOOL)textFieldShouldReturn:(UITextField *)textField {
    
        if (self.emailTextField == textField) {
            [self.passwordTextField becomeFirstResponder];
        } else {
            [self.emailTextField resignFirstResponder];
            [self.passwordTextField resignFirstResponder];
        }
        return NO;
    }
    - (void)viewWillAppear:(BOOL)animated {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    }
    
    #pragma mark - keyboard movements
    - (void)keyboardWillShow:(NSNotification *)notification
    {
        CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    
        [UIView animateWithDuration:0.3 animations:^{
            CGRect f = self.view.frame;
            f.origin.y = -0.5f * keyboardSize.height;
            self.view.frame = f;
        }];
    }
    
    -(void)keyboardWillHide:(NSNotification *)notification
    {
        [UIView animateWithDuration:0.3 animations:^{
            CGRect f = self.view.frame;
            f.origin.y = 0.0f;
            self.view.frame = f;
        }];
    }
    
    0 讨论(0)
  • 2020-11-28 20:51

    Based on Daniel Krom's solution. This is version in swift 3.0. Works great with AutoLayout, and moves whole view when keyboard appears.

    extension UIView {
    
        func bindToKeyboard(){
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
        }
    
        func unbindFromKeyboard(){
            NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
        }
    
        @objc
        func keyboardWillChange(notification: NSNotification) {
    
            guard let userInfo = notification.userInfo else { return }
    
            let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as! Double
            let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as! UInt
            let curFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
            let targetFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
            let deltaY = targetFrame.origin.y - curFrame.origin.y
    
            UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
                self.frame.origin.y += deltaY
            })
        }  
    }
    

    How to use it: Add bindToKeyboard function in viewDidLoad like:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        view.bindToKeyboard()
    }
    

    And add unbindFromKeyboard function in deinit:

    deinit {
        view.unbindFromKeyboard()
    }
    
    0 讨论(0)
提交回复
热议问题