我有一个Xcode 6应用程序使用Swift与多个视图。该应用程序由一系列收集用户响应的屏幕组成。
我想触发键盘上的uiview时,他们通过设置UITextFields作为第一响应者加载。我以以下方式注册了侦听器来响应键盘事件,因为在屏幕底部有控件,一个自定义菜单栏,需要向上滑动。
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
childAge.becomeFirstResponder()
//Register for keyboard notifications in order to reposition bottom menu
NSNotificationCenter.defaultCenter().addObserver(self, selector: "kbShown:", name: UIKeyboardDidShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "kbHidden:", name: UIKeyboardDidHideNotification, object: nil)
}
然后我删除viewwilldisappear事件中的监听器。
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self, name:UIKeyboardDidShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name:UIKeyboardDidHideNotification, object: nil)
}
这些代码块在所有UIViewController类中重复。然而,我的问题是,kbshow函数只在第一个视图中被正确触发。在随后的视图中,虽然触发了事件,但菜单栏没有按预期显示。
func kbShown(notification: NSNotification) {
let info = notification.userInfo as NSDictionary
let s:NSValue = info.valueForKey(UIKeyboardFrameEndUserInfoKey) as NSValue;
let rect :CGRect = s.CGRectValue(); //this is the KB rect
//Get Screen Size
var screenRect = UIScreen.mainScreen().bounds // [[UIScreen mainScreen] bounds];
var screenWidth = screenRect.size.width
var screenHeight = screenRect.size.height
var frame = self.menuBar.frame;
frame.origin.y = screenHeight - rect.height - frame.height //menuY! - rect.height;
self.menuBar.frame = frame;
}
func kbHidden(notification: NSNotification) {
var screenRect = UIScreen.mainScreen().bounds // [[UIScreen mainScreen] bounds];
var screenWidth = screenRect.size.width
var screenHeight = screenRect.size.height
var frame = self.menuBar.frame;
if (frame.origin.y != screenHeight - frame.height){
frame.origin.y = screenHeight - frame.height //frame.origin.y + rect.height;
self.menuBar.frame = frame;
}
}
我的菜单栏视图仍然隐藏在键盘下面。但是,如果我与知识库交互,如果我调整它的高度(在IOS8中有一个可以向下拖动的预测文本栏),那么菜单栏视图开始显示良好。
同样,如果我将第二个视图设置为第一个视图控制器,一切都可以正常工作。为此失去了几天,任何帮助都很感激。我做错了什么?
如果你在viewDidLoad
方法中注册了观察者,并在viewWillDisappear
中删除了它们,在第一次消失后,键盘处理方法不会再被调用,直到viewDidLoad被调用。
这是因为在视图控制器生命周期中,viewDidLoad
只在视图需要加载时调用,而不是在视图显示时调用。下一次可以再次加载相同的视图是在视图控制器被释放时,或者可能在视图不可见的内存警告事件期间。
将VC注册为键盘通知观察者的最佳位置是viewDidAppear
或viewWillAppear
。