我使用Swift与iOS编程,我使用这段代码来移动UITextField,但它不起作用。我正确地调用了函数keyboardWillShow,但是文本字段没有移动。我正在使用自动布局。
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self);
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
//let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
var frame = self.ChatField.frame
frame.origin.y = frame.origin.y - keyboardSize.height + 167
self.chatField.frame = frame
println("asdasd")
}
}
斯威夫特4。x答案,合并来自@Joseph Lord和@Isuru的答案。bottomConstraint表示你想移动的视图的底部约束。
override func viewDidLoad() {
// Call super
super.viewDidLoad()
// Subscribe to keyboard notifications
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardNotification(notification:)),
name: UIResponder.keyboardWillChangeFrameNotification,
object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc func keyboardNotification(notification: NSNotification) {
if let userInfo = notification.userInfo {
// Get keyboard frame
let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
// Set new bottom constraint constant
let bottomConstraintConstant = keyboardFrame.origin.y >= UIScreen.main.bounds.size.height ? 0.0 : keyboardFrame.size.height
// Set animation properties
let duration = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
let animationCurve = UIView.AnimationOptions(rawValue: animationCurveRaw)
// Animate the view you care about
UIView.animate(withDuration: duration, delay: 0, options: animationCurve, animations: {
self.bottomConstraint.constant = bottomConstraintConstant
self.view.layoutIfNeeded()
}, completion: nil)
}
}
Well, I think i might be too late but i found another simple version of Saqib's answer. I'm using Autolayout with constraints. I have a small view inside of another main view with username and password fields. Instead of changing the y coordinate of the view i'm saving the original constraint value in a variable and changing the constraint's constant to some value and again after the keyboard dismisses, i'm setting up the constraint to original one. This way it avoids the problem Saqib's answer has, (The view keeps on moving up and does not stop). Below is my code...
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
self.originalConstraint = self.centerYConstraint.constant
}
func keyboardWillShow(sender: NSNotification) {
self.centerYConstraint.constant += 30
}
func keyboardWillHide(sender: NSNotification) {
self.centerYConstraint.constant = self.originalConstraint
}
斯威夫特4。x答案,合并来自@Joseph Lord和@Isuru的答案。bottomConstraint表示你想移动的视图的底部约束。
override func viewDidLoad() {
// Call super
super.viewDidLoad()
// Subscribe to keyboard notifications
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardNotification(notification:)),
name: UIResponder.keyboardWillChangeFrameNotification,
object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc func keyboardNotification(notification: NSNotification) {
if let userInfo = notification.userInfo {
// Get keyboard frame
let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
// Set new bottom constraint constant
let bottomConstraintConstant = keyboardFrame.origin.y >= UIScreen.main.bounds.size.height ? 0.0 : keyboardFrame.size.height
// Set animation properties
let duration = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
let animationCurve = UIView.AnimationOptions(rawValue: animationCurveRaw)
// Animate the view you care about
UIView.animate(withDuration: duration, delay: 0, options: animationCurve, animations: {
self.bottomConstraint.constant = bottomConstraintConstant
self.view.layoutIfNeeded()
}, completion: nil)
}
}
这是一个通用的解决方案,为所有的TextField
步骤,
1)创建一个由其他ViewController扩展的通用ViewController
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y == 0 {
self.view.frame.origin.y -= getMoveableDistance(keyboarHeight: keyboardSize.height)
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if self.view.frame.origin.y != 0 {
self.view.frame.origin.y = 0
}
}
deinit {
NotificationCenter.default.removeObserver(self)
}
//get the distance to move up the main view for the focus textfiled
func getMoveableDistance(keyboarHeight : CGFloat) -> CGFloat{
var y:CGFloat = 0.0
if let activeTF = getSelectedTextField(){
var tfMaxY = activeTF.frame.maxY
var containerView = activeTF.superview!
while containerView.frame.maxY != self.view.frame.maxY{
let contViewFrm = containerView.convert(activeTF.frame, to: containerView.superview)
tfMaxY = tfMaxY + contViewFrm.minY
containerView = containerView.superview!
}
let keyboardMinY = self.view.frame.height - keyboarHeight
if tfMaxY > keyboardMinY{
y = (tfMaxY - keyboardMinY) + 10.0
}
}
return y
}
2)创建UIViewController和当前激活的TextField的扩展
//get active text field
扩展 UIViewController {
func getSelectedTextField() -> UITextField?{
let totalTextFields = getTextFieldsInView(view: self.view)
for textField in totalTextFields{
if textField.isFirstResponder{
return textField
}
}
return nil
}
func getTextFieldsInView(view: UIView) -> [UITextField] {
var totalTextFields = [UITextField]()
for subview in view.subviews as [UIView] {
if let textField = subview as? UITextField {
totalTextFields += [textField]
} else {
totalTextFields += getTextFieldsInView(view: subview)
}
}
return totalTextFields
}
}