鉴于 iOS 6 中对自动布局的关注以及 Apple 工程师的推荐(查看 WWDC 2012 视频)我们不再直接操作视图的框架,那么如何仅使用自动布局和 NSLayoutConstraint 来避免键盘呢?
Update
这看起来是一个合理的解决方案:键盘敏感布局示例 http://www.think-in-g.net/ghawk/blog/2012/09/practicing-auto-layout-an-example-of-keyboard-sensitive-layout/ (GitHub 源) https://github.com/ghawkgu/keyboard-sensitive-layout但我看到的一个潜在问题是,当用户旋转设备并且键盘已经在屏幕上时会发生什么?
这篇博文很棒,但我想提出一些改进建议。首先,您可以注册来观察帧变化,因此您不需要注册来观察显示和隐藏通知。其次,您应该将键盘的 CGRect 从屏幕坐标转换为视图坐标。最后,您可以复制 iOS 用于键盘本身的精确动画曲线,以便键盘和跟踪视图同步移动。
将所有这些放在一起,您将得到以下结果:
@interface MyViewController ()
// This IBOutlet holds a reference to the bottom vertical spacer
// constraint that positions the "tracking view",i.e., the view that
// we want to track the vertical motion of the keyboard
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomVerticalSpacerConstraint;
@end
@implementation MyViewController
-(void)viewDidLoad
{
[super viewDidLoad];
// register for notifications about the keyboard changing frame
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillChangeFrame:)
name:UIKeyboardWillChangeFrameNotification
object:self.view.window];
}
-(void)keyboardWillChangeFrame:(NSNotification*)notification
{
NSDictionary * userInfo = notification.userInfo;
UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] intValue];
NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
// convert the keyboard's CGRect from screen coords to view coords
CGRect kbEndFrame = [self.view convertRect:[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]
fromView:self.view.window];
CGRect kbBeginFrame = [self.view convertRect:[[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]
fromView:self.view.window];
CGFloat deltaKeyBoardOrigin = kbEndFrame.origin.y - kbBeginFrame.origin.y;
// update the constant factor of the constraint governing your tracking view
self.bottomVerticalSpacerConstraint.constant -= deltaKeyBoardOrigin;
// tell the constraint solver it needs to re-solve other constraints.
[self.view setNeedsUpdateConstraints];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:animationCurve];
[UIView setAnimationBeginsFromCurrentState:YES];
// within this animation block, force the layout engine to apply
// the new layout changes immediately, so that we
// animate to that new layout. We need to use old-style
// UIView animations to pass the curve type.
[self.view layoutIfNeeded];
[UIView commitAnimations];
}
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillChangeFrameNotification
object:nil];
}
@end
只要您在键盘打开时不改变方向,这就会起作用。
这是一个答案如何模仿iOS 7上的键盘动画向数字键盘添加“完成”按钮? https://stackoverflow.com/questions/18837166/how-to-mimic-keyboard-animation-on-ios-7-to-add-done-button-to-numeric-keyboar展示了如何正确模仿键盘动画曲线。
关于所有这些基于通知的解决方案要注意的最后一件事:如果应用程序中的其他屏幕也使用键盘,它们可能会产生意想不到的效果,因为只要视图控制器没有被释放,它仍然会收到通知,即使它的视图已卸载。解决此问题的一种方法是在通知处理程序中放置一个条件,以确保它仅在视图控制器位于屏幕上时才运行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)