我的应用程序中有一个功能,只要键盘显示,它就会向上移动视图。不幸的是有一个bug;第一次加载视图时一切正常,但如果切换到另一个视图,然后切换回来,视图就不再移动:(
我在代码中添加了一些NSLog
语句来尝试跟踪问题。我正在使用NSNotification,这工作正常,因为每次调用该方法。
然后我想也许这是视图坐标的问题,所以我添加了打印出视图原点的语句。他们打印出正确的原点('移动'原点),即使视图肯定没有移动。
所以似乎Xcode认为它已经移动了视图,但事实并非如此。还有其他人遇到过这种行为吗?
编辑:这是一些代码
设置通知:
//register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:self.view.window];
//if the keyboard is already being shown because someone was entering a comment, and then they switch to a textfield, this will move the view back down.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UITextFieldTextDidBeginEditingNotification object:self.view.window];
//hide the keyboard
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:self.view.window];
//hide the keyboard if we're done with the textview
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UITextViewTextDidEndEditingNotification object:self.view.window];
keyboardIsShown = FALSE;
tempDelegate.keyboardIsInitialized = TRUE;
显示键盘并移动视图的方法:
-(void)keyboardWillShow:(NSNotification *)notif{
NSLog(@"keyboardWillShow");
NSLog(@"type: %@, keyboardIsShown: %@", sender, keyboardIsShown);
//double check
if (keyboardIsShown || !sender) {
NSLog(@"return");
return;
}
//only adjust screen for comment box (which is a textview)
if(![sender isEqualToString:@"text field"] && [sender isEqualToString:@"text view"]){
NSLog(@"if");
NSDictionary* userInfo = [notif userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[UIView beginAnimations:@"ResizeForKeyboard" context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
NSLog(@"regular BEFORE: %@", NSStringFromCGRect(regularView.frame));
regularView.frame = CGRectMake(0, - keyboardSize.height, CGRectGetWidth(imageView.bounds)*scrollView.zoomScale, CGRectGetHeight(imageView.bounds)*scrollView.zoomScale);
NSLog(@"regular AFTER: %@", NSStringFromCGRect(regularView.frame));
[UIView commitAnimations];
keyboardIsShown = YES;
}
}
以及隐藏键盘并向后移动视图的方法:
-(void)keyboardWillHide:(NSNotification *)notif{
NSLog(@"keyboardWillHide");
if (!keyboardIsShown) {
NSLog(@"return");
return;
}
[UIView beginAnimations:@"ResizeForKeyboard" context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
NSLog(@"regular BEFORE: %@", NSStringFromCGRect(regularView.frame));
self.regularView.frame = CGRectMake(0, 0, CGRectGetWidth(imageView.bounds)*scrollView.zoomScale, CGRectGetHeight(self.imageView.bounds)*scrollView.zoomScale);
[UIView commitAnimations];
NSLog(@"regular AFTER: %@", NSStringFromCGRect(regularView.frame));
keyboardIsShown = NO;
}
答案 0 :(得分:1)
-(void) viewWillDisappear:(BOOL)animated {
NSLog (@"Unregister for keyboard events");
[[NSNotificationCenter defaultCenter]
removeObserver:self];
}
如果不是这样的话,请尝试检查viewWillAppear上视图的位置..如果它显示键盘已启动...使用动画解雇它。
答案 1 :(得分:1)
您是在regularView
还是viewWillAppear:
初始化viewDidAppear:
?如果是这种情况,您应该将初始化移至viewDidLoad
。
正如您确认的那样,解释是视图的生命周期可能会多次调用viewWillAppear:
,因此通常不适合在viewWillAppear:
中构建UI层次结构,因为您最终会重复的视图层次结构。
答案 2 :(得分:0)
您是否在任何时候添加或删除NSNotification?
另外,您是否可以发布代码以了解您的观点?那里可能存在一些问题。
编辑:
因此,看起来您的通知在某些时候被删除而没有被添加回来。
将通知init移至您的viewDidAppear
方法,然后使用viewDidDissappear
方法将其删除。这将确保无论何时您的视图出现或消失,都会分别添加或删除通知。
您可能正在做的是在viewDidLoad中添加它们,此方法仅在首次加载视图时被调用(因此仅一次)。因此,如果您推送一个新视图然后弹回,它们可能会被删除而不会被添加回来。
编辑:
以下是我需要使用键盘设置动画时常用的代码。
#define kOFFSET_FOR_KEYBOARD 80.0
-(void)keyboardWillShow {
// Animate the current view out of the way
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)keyboardWillHide {
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if ([sender isEqual:mailTf])
{
//move the main view, so that the keyboard does not hide it.
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
}
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // if you want to slide up the view
CGRect rect = self.view.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
else
{
// revert back to the normal state.
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
[UIView commitAnimations];
}
- (void)viewWillAppear:(BOOL)animated
{
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}