textFieldDidBeginEditing过早地称为(textFieldDidBeginEdi

2019-08-02 15:11发布

我具有其中我在键盘显示的情况下,向上滚动的应用程序。 让键盘的大小,我注册,像这样的UIKeyboardWillShowNotification事件:

   [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(keyboardWillShow:)
     name:UIKeyboardWillShowNotification
     object:self.view.window]

这并不工作,但问题是,它被称为textFieldDidBeginEditing被称为后。 所以,我不能得到实际的键盘尺寸,但只有后场已经在编辑模式下,这违背了第一个地方注册本次活动的全部目的。 我敢肯定,我已经叫UIKeyboardWillShowNotification而不是UIKeyboardDidShowNotification,尽管切换这两个产生相同的结果:第一个电话是给委托方法制成然后才通知方法。 如何扭转这个局面的任何想法? 目前,我硬编码的大小,这是非常不好的做法?

Answer 1:

我建议一个GitHub的库

https://github.com/hackiftekhar/IQKeyboardManager



Answer 2:

下面是我对这个使用exactly.It写了一个基类的子类UIViewController每当我想实现这样的行为,我只是做我的视图控制器子类这个基类的。

顺便说一句 - 你是对的。 textFieldDidBeginEditing键盘显示出来后,这就是为什么你要为我的类描述在键盘的回调方法向上滚动被调用。

同时请注意,这个工作你需要嵌入在滚动查看整个视图,并连接滚动视图,以它的IBOutlet中。

如果您使用的不是故事板卸下IBOutlet中的一部分,并嵌入您的视图中滚动视图,并在代码中的连接。

此说这里后的代码:

头文件

#import <UIKit/UIKit.h>

@interface BaseViewControllerWithKeyboard : BaseViewController

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

@end

实现文件

#import "BaseViewControllerWithKeyboard.h"

@interface BaseViewControllerWithKeyboard ()

@end

@implementation BaseViewControllerWithKeyboard

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self registerForKeyboardNotifications];
}

- (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;
}

@end


Answer 3:

我在XCode中5开了一个新的项目,增加了一个UITextFieldViewController和连接它的委托。

这是我唯一的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myNotificationMethod:) name:UIKeyboardWillShowNotification object:nil];
}

- (void)myNotificationMethod:(NSNotification*)notification
{
    NSDictionary* keyboardInfo = [notification userInfo];
    NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
    NSLog(@"Rect: %@",NSStringFromCGRect(keyboardFrameBeginRect));
}

这里的日志输出:

Portraid:

 Rect: {{0, 480}, {320, 216}}

景观:

 Rect: {{-162, 0}, {162, 480}}

编辑:

关于textFieldDidBeginEditing之前被称为name:UIKeyboardWillShowNotification ,我真的不明白,为什么有区别,如果文本框是在编辑模式下或没有,但也有解决这几个方面。

  1. 保存参考从textFieldShouldBeginEditing文本框,并使用它里面myNotificationMethod如果没有textFieldShouldBeginEditing被触发。

  2. 玩弄UIResponder像这样:

textFieldDidBeginEditing - >保存到一个参考UIResponder并改变UIResponder到一个临时不相干之一。 在myNotificationMethod做你想要做的文本框(是不是在编辑模式\第一响应者)什么都,当您完成让你的主要UIResponder



Answer 4:

根据苹果的文档UIKeyboardWillShowNotification被称为将要显示的键盘之前,而UITextFieldDidBeginEditing被称为刚过文本字段成为第一个响应者。 该过程显示的文本字段成为第一个响应,且仅当键盘尚未显示的键盘开始。 这意味着UIKeyboardWillShowNotificationUITextFieldDidBeginEditing后调用。 所以UITextFieldDidBeginEditing不会过早地被调用。

如果你只是想向上滚动,使文本字段不会下键盘被隐藏,你可以设置内容滚动视图在UITextFieldShouldBeginEditingUITextFieldDidBeginEditing文本字段的y原点偏移。



Answer 5:

老问题,但我今天遇到了同样的问题。 我建立了一个有点“脏”的解决办法,不逼我硬编码键盘大小。 我只是做了以下的viewDidAppear(注意 - 斯威夫特):

 override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    self.infoTextField.becomeFirstResponder()
    self.infoTextField.resignFirstResponder()
}

这触发了UIKeyboardWillShowNotification,你可以从通知获取键盘的大小,并将其存储在一个属性。 希望这可以帮助别人,它的工作在我的情况。



文章来源: textFieldDidBeginEditing is called prematurely