我正在创建一个应用程序,在其中我有一个动画,当键盘出现时,它会重新定位UILabel
和UITextField
。它设置如下:
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(raiseTextField), name: UIKeyboardWillShowNotification, object: nil)
这就是功能:
func raiseTextField(sender: NSNotification){
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.userInputTextFieldBottomContstraint.constant = sender.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue().size.height
self.view.layoutIfNeeded()
})
}
我设置了约束,以便friendInputView
的大小正确,并且自动收缩,因此字体会相应调整。
当我拨打raiseTextField()
时,一切正常,但friendInputView
的字体大小需要很长时间才能更改。在动画发生时而不是更新,它会在之后更新 。
它最终会调整,而不是以首选速度调整。
我尝试在self.friendInputLabel.adjustsFontSizeToFitWidth = true
内添加animateWithDuration()
,但似乎没有改变任何内容。
(正确调整文字)
(文字太大)
(正确调整文字)
有没有办法让UILabel
以编程方式调整文本大小,而不是仅仅等待它自己更新?与layoutIfNeeded()
重新调整约束的方式类似,是否有任何函数可以重新调整自动收缩?
我最终根据我得到的答案表示使用UITextFieldDelegate
代替NSNotificationCenter
来开始工作。我用以下代码替换了raiseTextField()
函数:
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
self.userInputTextFieldBottomContstraint.constant = 250
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.layoutIfNeeded()
})
return true
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
self.userInputTextFieldBottomContstraint.constant = 10
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.layoutIfNeeded()
})
return true
}
但是,现在我有一个新问题:如何才能使用真正的键盘大小?假设键盘大小始终为250并不是很有帮助。
我尝试通过创建此变量来实现:
var keyboardHeight: CGFloat?
将其放入viewDidLoad()
:
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(setTheKeyboardHeight), name: UIKeyboardWillShowNotification, object: nil)
创建此功能:
func setTheKeyboardHeight(sender: NSNotification){
keyboardHeight = sender.userInfo![UIKeyboardFrameEndUserInfoKey]?.CGRectValue().height
}
然后我将其添加到textFieldShouldBeginEditing()
,如下所示:
self.userInputTextFieldBottomContstraint.constant = keyboardHeight!
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.layoutIfNeeded()
})
return true
然而,它最终只是给出错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
我认为这是因为keyboardHeight
在 textFieldShouldBeginEditing()
被调用后被设置为,但我不知道如何修复它。
使用textFieldShouldBeginEditing()
时有什么方法可以访问键盘高度,还是必须使用NSNotificationCenter
?
答案 0 :(得分:0)
我已经完成了你所做的相同的演示,并观察了UIKeyboardNotification的一些奇怪的行为,我不确定它是奇怪的还是只是那样,
我观察到的是当您更改UIKeyboardNotification中的任何约束时,它会使用动画更改约束常量(或帧),即使您尚未使用UIView animationWithDuration块。所以我认为这种延迟可能是由于KeyboardNotification添加的动画效果,
func raiseTextField(sender: NSNotification){
self.bottomConstraintTextField.constant = 250//sender.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue().size.height
self.view.setNeedsUpdateConstraints()
//As you can see i have commented the animation block, still it changes the constraint with animation.
//UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.layoutIfNeeded()
//})
}
所以在你的场景中我已经在textFields委托中添加了动画代码,它按预期工作了,
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
self.bottomConstraintTextField.constant = 250//sender.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue().size.height
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.layoutIfNeeded()
})
return true
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
self.bottomConstraintTextField.constant = 10
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.layoutIfNeeded()
})
return true
}
结果如下,
希望它对你有所帮助。
<强>更新强>
我已经玩了它并发现了一个解决方法,所以不是采用变量来保持键盘高度,你可以按照下面的方式进行操作,
func raiseTextField(sender: NSNotification){
self.bottomConstraintTextField.constant = sender.userInfo![UIKeyboardFrameEndUserInfoKey]!.CGRectValue().size.height
self.view.setNeedsUpdateConstraints()
self.view.layoutIfNeeded()
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
self.bottomConstraintTextField.constant = 200
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.layoutIfNeeded()
})
return true
}
同时拥有textField委托和KeyboardNotification并更改textField委托中的底部约束,它将在键盘通知之前被调用,通过这样做,您将不会观察缩小标签文本的延迟。
请参阅下面的更新效果,