问题陈述:我有UIView的Nib文件包含UIScrollview,在scrollview中我有几个TextFields和一个TextView在底部。我想要的是在textfield或Textview开始编辑时向上滚动。
我尝试了什么:
在客户方法
中NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
我正在调用此方法父视图。
通知处理:
func keyboardWasShown(notification: NSNotification)
{
var userInfo = notification.userInfo!
var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
keyboardFrame = self.convert(keyboardFrame, from: nil)
var contentInset:UIEdgeInsets = self.mainScroll.contentInset
contentInset.bottom = keyboardFrame.size.height
self.mainScroll.contentInset = contentInset
}
这对UITextFields非常有效,但不适用于UITextView。知道哪里出错了。
PS:我也设置了UITextField和UITextView的代理。
任何帮助将不胜感激。
答案 0 :(得分:1)
演示链接:https://github.com/harshilkotecha/UIScrollViewWhenKeyboardAppearInSwift3
当你有多个textview时,它是如此困难,所以最好的解决方案 - >
第1步:添加 UITextFieldDelegate
class ScrollViewController: UIViewController,UITextFieldDelegate {
第2步:创建新的IBOutlet,但不要与任何文本字段连接
// get current text box when user Begin editing
@IBOutlet weak var activeTextField: UITextField?
步骤3:当用户关注文本字段对象传递引用并存储在activeTextField中时,编写这两个方法
// get current text field
func textFieldDidBeginEditing(_ textField: UITextField)
{
activeTextField=textField;
}
func textFieldDidEndEditing(_ textField: UITextField)
{
activeTextField=nil;
}
第5步:在viewdidload中设置通知 setNotificationKeyboard
override func viewWillAppear(_ animated: Bool) {
// call method for keyboard notification
self.setNotificationKeyboard()
}
// Notification when keyboard show
func setNotificationKeyboard () {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: .UIKeyboardWillHide, object: nil)
}
第6步:隐藏和显示键盘的两种方法
func keyboardWasShown(notification: NSNotification)
{
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height+10, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeField = self.activeTextField
{
if (!aRect.contains(activeField.frame.origin))
{
self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
}
}
}
// when keyboard hide reduce height of scroll view
func keyboardWillBeHidden(notification: NSNotification){
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0,0.0, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
self.view.endEditing(true)
}
答案 1 :(得分:0)
用以下函数替换keyboardWasShown函数:
func keyboardWasShown(notification: NSNotification)
{
var userInfo = notification.userInfo!
var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
keyboardFrame = self.convert(keyboardFrame, from: nil)
self.mainScroll.contentOffset = CGPoint(x: 0, y: keyboardFrame.size.height - Any number that fits your need.)
}
在keyBoardWillHide中:
self.mainScroll.contentOffset = CGPoint(x: 0, y: 0)
希望它会有所帮助。 快乐的编码!
答案 2 :(得分:0)
快捷键5
NotificationCenter.default.addObserver(self, selector: #selector(keyboardNotification), name: UIResponder.keyboardDidChangeFrameNotification, object: nil)
@objc func keyboardNotification(_ notification: Notification) {
if let userInfo = (notification as NSNotification).userInfo {
let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let duration:TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions().rawValue
let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
if (endFrame?.origin.y)! >= UIScreen.main.bounds.size.height {
scrollViewBottomConstraint?.constant = 0
} else {
if tabBarController?.tabBar.frame == nil {
return
}
scrollViewBottomConstraint?.constant = endFrame!.size.height - (tabBarController?.tabBar.frame.height)!
let bottomOffset = CGPoint(x: 0, y: 0)
scrollView.setContentOffset(bottomOffset, animated: true)
}
UIView.animate(withDuration: duration, delay: 0, options: animationCurve, animations: { self.view.layoutIfNeeded() }, completion: nil)
}
}
用法:
1.connect the scrollView outlet to your controller and set its name to 'scrollView'
2.connect the scrollView bottom constraint to your controller & set its name to 'scrollViewBottomConstraint'
3.put the notification observer to your ViewDidLoad function.