textFieldDidBeginEditing被提前调用
我有一个应用程序,我必须在键盘显示的情况下向上滚动。 为了获得键盘大小,我正在注册UIKeyboardWillShowNotification事件,如下所示:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window]
这确实奏效,问题在于,在调用textFieldDidBeginEditing之后调用它。 所以,我不能得到实际的键盘大小,但只有在该字段已处于编辑模式之后,才能实现注册此事件的整体目的。 我确定我已经调用了UIKeyboardWillShowNotification而不是UIKeyboardDidShowNotification ,尽管切换这两个结果会产生相同的结果:首先调用委托方法,然后才调用通知方法。 任何想法如何扭转这种情况? 目前我很难编码大小,这是非常糟糕的做法...
我可以建议一个GitHub存储库
https://github.com/hackiftekhar/IQKeyboardManager
这是我为这个用途写的一个基类。它是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
我在XCode 5中打开了一个新项目,向ViewController
添加了一个UITextField
,并连接了它的委托。
这是我唯一的代码:
- (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}}
编辑:
关于在name:UIKeyboardWillShowNotification
之前调用textFieldDidBeginEditing
,我不明白为什么如果textField处于编辑模式或者不是,但有几种方法可以解决这个问题。
从textFieldShouldBeginEditing中保存对textField的引用,并在myNotificationMethod中使用它,如果intextFieldShouldBeginEditing被触发。
像这样玩UIResponder
:
在textFieldDidBeginEditing
- >保存到一个参考UIResponder
并改变UIResponder
到一个临时不相干之一。 在myNotificationMethod
,当您完成将其设置为主要UIResponder
时,对textField执行任何操作(即不在编辑模式 first responder中)。