我有一个应用程序,在键盘显示的情况下我必须向上滚动。 为了获得键盘大小,我正在注册 UIKeyboardWillShowNotification 事件:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window]
这确实有效,问题是,在调用 textFieldDidBeginEditing 之后调用它。因此,我无法获得实际的键盘大小,但只有在该字段已经处于编辑模式之后,这才会在首先注册此事件的整个目的。 我确定我已经调用 UIKeyboardWillShowNotification 而不是 UIKeyboardDidShowNotification ,虽然切换这两个会产生相同的结果: 首先调用delegate方法,然后调用通知方法。关于如何扭转局面的任何想法?目前我很难编码大小,这是非常糟糕的做法...
答案 0 :(得分:2)
我可以建议一个GitHub存储库
答案 1 :(得分:1)
这是我为此用途编写的基类。它是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
答案 2 :(得分:0)
我在XCode 5中打开了一个新项目,向UITextField
添加了ViewController
并连接了其代理人。
这是我唯一的代码:
- (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
,我真的不明白为什么textField处于编辑模式会有区别,但有几种方法可以解决这个问题。
从textFieldShouldBeginEditing保存对textField的引用,并在myNotificationMethod中使用它,如果在textFieldShouldBeginEditing中被触发了。
如此使用UIResponder
:
textFieldDidBeginEditing
中的 - &gt;保存对UIResponder
的引用,并将UIResponder
更改为不相关的临时值。在myNotificationMethod
中执行您想要对textField执行的操作(不在编辑模式\第一响应程序中),完成后将其设为主UIResponder
。
答案 3 :(得分:0)
根据Apple文档,在显示键盘之前调用 UIKeyboardWillShowNotification ,而在文本字段成为第一响应者之后立即调用 UITextFieldDidBeginEditing 。显示键盘的过程在文本字段成为第一响应者后 后启动,并且仅在键盘尚未显示时启动。这意味着将在 UITextFieldDidBeginEditing 之后调用 UIKeyboardWillShowNotification 。因此,不会过早调用 UITextFieldDidBeginEditing 。
如果您只想向上滚动以便文本字段不会隐藏在键盘下,您只需将滚动视图的内容偏移设置为 UITextFieldShouldBeginEditing中的文本字段的y-origin 或 UITextFieldDidBeginEditing 。
答案 4 :(得分:0)
老问题,但今天我遇到了同样的问题。我已经构建了一个“脏”的解决方法,不会强迫我硬编码键盘大小。我只是在viewDidAppear(注意 - Swift)中执行了以下操作:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.infoTextField.becomeFirstResponder()
self.infoTextField.resignFirstResponder()
}
这会触发 UIKeyboardWillShowNotification ,您可以从通知中获取键盘大小并将其存储在属性中。希望这对某人有所帮助,它在我的案例中起作用。