当键盘在文本字段上时,ios 移动滚动视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20233587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:31:31  来源:igfitidea点击:

ios move scrollview when keyboard is over text field

iosobjective-c

提问by ruby_ruby

please, could you correct my code, so i have an example of simple app with text field which moves up when keyboard is over it?

拜托,你能更正我的代码吗,所以我有一个简单的应用程序示例,它带有文本字段,当键盘在上面时它会向上移动?

I tried to implement it using code from from ios developer library https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

我尝试使用来自 ios 开发人员库https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html 的代码来实现它

but i don't know what they mean by "The active field is stored in a custom variable (called activeField in this example)" and I did probably something else wrong. Using registerForKeyboardNotifications in viewWillAppear is ok?

但我不知道“活动字段存储在自定义变量(在本例中称为 activeField)中”是什么意思,而且我可能做错了其他事情。在 viewWillAppear 中使用 registerForKeyboardNotifications 可以吗?

I know there are some threads about this problem, but I am newbie and it's hard to understand them for me. And I don't want to just learn how, but why, that's why I don't want to use ready to use solution from github others advised etc.

我知道有一些关于这个问题的线索,但我是新手,我很难理解它们。而且我不想只是学习如何,但为什么,这就是为什么我不想使用来自其他人建议的 github 等的现成解决方案。

My code atm:

我的代码自动取款机:

.h:

。H:

#import <UIKit/UIKit.h>

@interface VNViewController : UIViewController<UIScrollViewDelegate, UITextFieldDelegate>

@property (weak, nonatomic) IBOutlet UITextField *texticek;
@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;

@end

.m:

.m:

#import "VNViewController.h"

@interface VNViewController ()

@end


@implementation VNViewController

@synthesize scrollView;
@synthesize texticek;

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self registerForKeyboardNotifications];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillBeHidden:)
                                             name:UIKeyboardWillHideNotification object:nil];

}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your app might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        [self.scrollView scrollRectToVisible:activeField.frame animated:YES];
    }
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    activeField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    activeField = nil;
}

@end

回答by venky

Moving up textfield while clicking it, use below code . it requires only outlet of your scroll

单击时向上移动文本字段,使用下面的代码。它只需要你的卷轴出口

- (void)textFieldDidBeginEditing:(UITextField *)textField {

    self.scroll.contentOffset = CGPointMake(0, textField.frame.origin.y);
}

you can change the position of textfield where should appear by minus the y position value (textfield.frame.origin.y - some value)

您可以通过减去 y 位置值来更改文本字段的位置(textfield.frame.origin.y - 某个值)

If you want to animate the scroll you can do like this :

如果你想动画滚动,你可以这样做:

CGPoint newOffset = CGPointMake(0, textField.frame.origin.y-40);
[self.scroll setContentOffset: newOffset animated: YES];

回答by Sudheer Kumar Palchuri

In ViewDidLoad, register the notifications:

在 ViewDidLoad 中,注册通知:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillBeHidden:)
                                             name:UIKeyboardWillHideNotification object:nil];

Add below observer methods which does the automatic scrolling when keyboard appears.

添加以下观察者方法,当键盘出现时自动滚动。

- (void)keyboardWasShown:(NSNotification*)notification
   {
        NSDictionary *info = [notification userInfo];
        CGRect keyboardRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
        keyboardRect = [self.view convertRect:keyboardRect fromView:nil];

        UIEdgeInsets contentInset = self.scrollView.contentInset;
        contentInset.bottom = keyboardRect.size.height;
        self.scrollView.contentInset = contentInset;
    }

    - (void)keyboardWillBeHidden:(NSNotification*)notification
    {
        UIEdgeInsets contentInsets = UIEdgeInsetsZero;
        self.scrollView.contentInset = contentInsets;
    }

    #pragma mark TextField Delegates
    - (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        [textField resignFirstResponder];
        return YES;
    }

回答by Homam

Here is the solution using Swift:

这是使用 Swift 的解决方案:

import UIKit

class ExampleViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var scrollView: UIScrollView!

    @IBOutlet var textField1: UITextField!
    @IBOutlet var textField2: UITextField!
    @IBOutlet var textField3: UITextField!
    @IBOutlet var textField4: UITextField!
    @IBOutlet var textField5: UITextField!

    var activeTextField: UITextField!

    // MARK: - View
    override func viewDidLoad() {
        super.viewDidLoad()
        self.textField1.delegate = self
        self.textField2.delegate = self
        self.textField3.delegate = self
        self.textField4.delegate = self
        self.textField5.delegate = self
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        self.registerForKeyboardNotifications()
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        self.unregisterFromKeyboardNotifications()
    }

    // MARK: - Keyboard

    // Call this method somewhere in your view controller setup code.
    func registerForKeyboardNotifications() {
        let center:  NSNotificationCenter = NSNotificationCenter.defaultCenter()
        center.addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil)
        center.addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
    }

    func unregisterFromKeyboardNotifications () {
        let center:  NSNotificationCenter = NSNotificationCenter.defaultCenter()
        center.removeObserver(self, name: UIKeyboardDidShowNotification, object: nil)
        center.removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
    }

    // Called when the UIKeyboardDidShowNotification is sent.
    func keyboardWasShown (notification: NSNotification) {
        let info : NSDictionary = notification.userInfo!
        let kbSize = (info.objectForKey(UIKeyboardFrameBeginUserInfoKey)?.CGRectValue() as CGRect!).size

        let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
        scrollView.contentInset = contentInsets;
        scrollView.scrollIndicatorInsets = contentInsets;

        // If active text field is hidden by keyboard, scroll it so it's visible
        // Your app might not need or want this behavior.
        var aRect = self.view.frame
        aRect.size.height -= kbSize.height;
        if (!CGRectContainsPoint(aRect, self.activeTextField.frame.origin) ) {
            self.scrollView.scrollRectToVisible(self.activeTextField.frame, animated: true)
        }
    }

    // Called when the UIKeyboardWillHideNotification is sent
    func keyboardWillBeHidden (notification: NSNotification) {
        let contentInsets = UIEdgeInsetsZero;
        scrollView.contentInset = contentInsets;
        scrollView.scrollIndicatorInsets = contentInsets;
    }

    // MARK: -  Text Field

    func textFieldDidBeginEditing(textField: UITextField) {
        self.activeTextField = textField
    }

    func textFieldDidEndEditing(textField: UITextField) {
        self.activeTextField = nil
    }

}

回答by Vinodh

BSKeyboardControlis a nice control . You need to provide text-fields in your view . An implement some of it delegate method. Then it's too simple to do this . A toolbar with previous and next button available to loop through the text-fields present . Following link will give you detail explanation about BSKeyboardControl

BSKeyboardControl是一个不错的控件。您需要在视图中提供文本字段。一个实现它的一些委托方法。那么这样做就太简单了。带有上一个和下一个按钮的工具栏可用于循环显示当前的文本字段。以下链接将为您提供有关BSKeyboardControl 的详细说明

https://github.com/simonbs/BSKeyboardControls#usage

https://github.com/simonbs/BSKeyboardControls#usage

回答by payal

Change in one function:

一项功能的改变:

- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;

// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
    [scrollView setContentOffset:CGPointMake(0,aRect.size.height) animated:YES];
}}

回答by jianAjian

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    //添加键盘弹出通知
    [[NSNotificationCenter defaultCenter]addObserver:self  selector:@selector(didChangeKeyBoardFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

-(void)viewDidAppear:(BOOL)animated
{
    //设置原始contentSize;
    [super viewDidAppear:animated];
    originalSize = self.mscrollView.contentSize;
}

-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    //移除键盘弹出通知
    [[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
}

pragma mark - private

pragma mark - 私有

-(void)didChangeKeyBoardFrame:(NSNotification *)sender
{
    CGRect  endRect  = [[sender.userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];

    CGPoint  mf =[self.view convertPoint:CGPointMake(0,self.name_textfieldDown.frameBottom) fromView:self.mscrollView];

    //does the keyboard  cover my label
    CGFloat distance =   mf.y  - endRect.origin.y;

    // it  mean that keyboard will hidden
    if(endRect.origin.y == ScreenHeight)
    {
        // place scrollView back
        [UIView animateWithDuration:0.25 animations:^{
                    self.mscrollView.contentOffset = CGPointMake(0,  self.mscrollView.contentSize.height-  self.mscrollView.height);
            self.mscrollView.contentSize = originalSize;
        }];
    }
    else if (distance>0)
    {
        //
        [UIView animateWithDuration:0.25 animations:^{
            CGSize contentSize = originalSize;
            contentSize.height +=( endRect.size.height  ) ;// I want  users can drag scrollView to buttom when keyboard is showing
            self.mscrollView.contentSize = contentSize;
            self.mscrollView . contentOffset = CGPointMake(0, self.mscrollView.contentOffset.y + distance+20);
        }];
    }
}

回答by Navin Amulani

UITextField *activeField; for activeField you have to declare in .m file

UITextField *activeField; 对于 activeField 你必须在 .m 文件中声明