How to make a UIScrollView auto scroll when a UITextField becomes a first responder

前端 未结 11 1800
有刺的猬
有刺的猬 2021-01-31 03:24

I\'ve seen posts around here that suggest that UIScrollViews should automatically scroll if a subview UITextField becomes the first responder; however,

相关标签:
11条回答
  • 2021-01-31 03:33

    Building off of Vasily Bodnarchuk's answer I created a gist with a simple protocol that you can implement and it'll do it all for you. All you need to do is call registerAsTextDisplacer()

    I created a BaseViewController in my project and made that implement it

    https://gist.github.com/CameronPorter95/cb68767f5f8052fdc70293c167e9430e

    0 讨论(0)
  • 2021-01-31 03:34

    I hope this example will help you You can scroll to any point by this code.

    scrollView.contentOffset = CGPointMake(0,0);
    

    So if you have textfield, it must have some x,y position on view, so you can use

    CGPoint point = textfield.frame.origin ;
    scrollView.contentOffset = point 
    

    This should do the trick,

    But if you don't know when to call this code, so you should learn UITextFieldDelegate methods

    Implement this method in your code

    - (void)textFieldDidBeginEditing:(UITextField *)textField {
    // Place Scroll Code here
    }
    

    I hope you know how to use delegate methods.

    0 讨论(0)
  • 2021-01-31 03:40

    Here is the Swift 4 update to @Supertecnoboff's answer. It worked great for me.

    func textFieldDidBeginEditing(_ textField: UITextField) {
        scroll.setContentOffset(CGPoint(x: 0, y: (textField.superview?.frame.origin.y)!), animated: true)
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        scroll.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
    }
    

    Make sure to extend UITextFieldDelegate and set the textfields' delegate to self.

    0 讨论(0)
  • 2021-01-31 03:40

    If you have multiple textfields say Textfield1, Textfield2, Textfield3 and you want to scroll the scrollview along the y-axis when textfield2 becomes first responder:

    if([Textfield2 isFirstResponder])
    {
        scrollView.contentOffset = CGPointMake(0,yourY);
    } 
    
    0 讨论(0)
  • 2021-01-31 03:41

    You can use this function for autoScroll of UITextField

    on UITextFieldDelegate

    - (void)textFieldDidBeginEditing:(UITextField *)textField {
    
    [self autoScrolTextField:textField onScrollView:self.scrollView];
    }
    
    
    
    
    - (void) autoScrolTextField: (UITextField *) textField onScrollView: (UIScrollView *) scrollView { 
     float slidePoint = 0.0f;
    float keyBoard_Y_Origin = self.view.bounds.size.height - 216.0f;
    float textFieldButtomPoint = textField.superview.frame.origin.y + (textField.frame.origin.y + textField.frame.size.height);
    
    if (keyBoard_Y_Origin < textFieldButtomPoint - scrollView.contentOffset.y) {
        slidePoint = textFieldButtomPoint - keyBoard_Y_Origin + 10.0f;
        CGPoint point = CGPointMake(0.0f, slidePoint);
        scrollView.contentOffset = point;
    }
    

    EDIT:

    Im now using IQKeyboardManager Kudos to the developer of this, you need to try this.

    0 讨论(0)
  • 2021-01-31 03:43

    Other solutions I saw, let you set the offset to the origin of the textField but this makes the scroller view go beyond it bounds. I did this adjustment to the offset instead to not go beyond the bottom nor the top offsets.

    Set the keyboardHeightConstraint to the bottom of the page. When the keyboard shows, update its constraint's constant to negative the keyboard height. Then scroll to the responderField as we will show below.

    @IBOutlet var keyboardHeightConstraint: NSLayoutConstraint?
    var responderField: String?
    
    @objc func keyboardNotification(notification: NSNotification) {
         guard let keyboardValue = notification.userInfo [UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
         let keyboardHeight = keyboardValue.cgRectValue.height
    
         keyboardHeightConstraint?.constant = -keyboardHeight
         scroll(field: responderField!)
    }
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
         responderField = textField
    }
    

    Now we want to make sure we do not scroll greater than the bottom offset nor less than the top offset. At the same time, we want to calculate the offset of the field's maxY value. To do that, we subtract the scrollView.bounds.size.height from the maxY value.

    let targetOffset = field.frame.maxY - scrollView.bounds.size.height

    I found it nicer to scroll an extra distance of the keyboard height, but you could neglect that if you want to scroll right below the field.

    let targetOffset = keyboardHeight + field.frame.maxY - scrollView.bounds.size.height

    Remember to add the scrollView.contentInset.bottom if you have the tab bar visible.

    func scroll(field: UITextField) {
            guard let keyboardConstraintsConstant = keyboardHeightConstraint?.constant else { return }
            let keyboardHeight = -keyboardConstraintsConstant
            
            view.layoutIfNeeded()
            let bottomOffset = scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom
            let topOffset = -scrollView.safeAreaInsets.top
            let targetOffset = keyboardHeight + field.frame.maxY + scrollView.contentInset.bottom - scrollView.bounds.size.height
            let adjustedOffset = targetOffset > bottomOffset ? bottomOffset : (targetOffset < topOffset ? topOffset : targetOffset)
            scrollView.setContentOffset(CGPoint(x: 0, y: adjustedOffset), animated: true)
    }
    
    0 讨论(0)
提交回复
热议问题