简体   繁体   English

滚动视图和键盘问题Swift

[英]Scroll view and keyboard issue Swift

I have a view controller with scrollview inside and I set it in this way (with autolayout) in storyboard: 我有一个内部带有scrollview的视图控制器,并在情节提要板上以这种方式(使用自动布局)进行了设置:

Example

As you can see I add all objects in the last view (called 'viewsotto') inside in the scrollview. 如您所见,我在滚动视图的最后一个视图(称为“ viewsotto”)中添加了所有对象。 My problem is that: Some of these objects are textfield and I want that when I tap on it and keyboard shows it can be down the textfield so that I can see what I write in it. 我的问题是:这些对象中的一些是文本字段,我希望当我点击它并在键盘上显示它可以在文本字段下方时,才能看到我在其中写的内容。 For this reason I do it in this way: 因此,我这样做:

NotificationCenter.default.addObserver(self, selector: #selector(userProfiloGiusto.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(userProfiloGiusto.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

func keyboardWillShow(notification: NSNotification) {

        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y == 0{
                self.view.frame.origin.y -= keyboardSize.height
            }
        }

    }

    func keyboardWillHide(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y != 0{
                self.view.frame.origin.y += keyboardSize.height
            }
        }
    }

but it doesn't work. 但这不起作用。 What am I doing wrong? 我究竟做错了什么?

Try below code. 尝试下面的代码。 Firstly add var activeField: UITextField? 首先添加var activeField: UITextField? to check is textfield availability. 检查文本字段的可用性。 Then in view did load call this function: 然后在视图中确实调用了此函数:

override func viewDidLoad() {
    super.viewDidLoad()self.registerForKeyboardNotifications()

    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard))
    view.addGestureRecognizer(tap)
    tap.cancelsTouchesInView = false}


func registerForKeyboardNotifications()
{
    //Adding notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ProfileReviewViewController.keyboardWasShown(_:)), name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ProfileReviewViewController.keyboardWillBeHidden(_:)), name: UIKeyboardWillHideNotification, object: nil)
}


func deregisterFromKeyboardNotifications()
{
    //Removing notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWasShown(notification: NSNotification)
{
    //Need to calculate keyboard exact size due to Apple suggestions
    let info : NSDictionary = notification.userInfo!
    let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
    let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)


    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if activeField != nil
    {
        if (CGRectContainsPoint(aRect, activeField!.frame.origin))
        {
            scrollView.scrollRectToVisible(activeField!.frame, animated: true)
        }
    }
}

func keyboardWillBeHidden(notification: NSNotification)
{
    self.scrollView.contentInset = UIEdgeInsetsZero
}
//MARK : Textfield delegate methods
func textFieldDidBeginEditing(textField: UITextField) {
    activeField = textField
}

func textFieldShouldReturn(textField: UITextField) -> Bool {

    self.view.endEditing(true)
    activeField = nil
    return false
}
func textFieldShouldEndEditing(textField: UITextField) -> Bool {  //delegate method

    activeField = nil
    return true
}
func dismissKeyboard() {
    //Causes the view (or one of its embedded text fields) to resign the first responder status.

    activeField = nil
    view.endEditing(true)
}

Most probably the readings you are using to understand if there is overlapping are not correct. 您用来理解是否有重叠的读数很可能不正确。
It's a common issue, you are confronting them with your main view, instead you should get the frame of the textfield, make the right conversion to see if the keyboard is overlapping it and adjust the content inset of the scrollview accordingly.z 这是一个常见的问题,您需要通过主视图来面对它们,而是应该获取文本字段的框架,进行正确的转换以查看键盘是否与之重叠,并相应地调整scrollview的内容插图。
This is well explained in the Managing the keyboard documentation. 管理键盘文档中对此进行了很好的说明。
When the keyboard is shown: 显示键盘时:

func keyboardWasShown(notification: NSNotification)
{
    let info : NSDictionary = notification.userInfo!
    let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size!
    let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height, 0.0)


    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your app might not need or want this behavior.
    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize.height
    if let actField = activeField
    {
        if (CGRectContainsPoint(aRect, actField.frame.origin))
        {
            scrollView.scrollRectToVisible(actField.frame, animated: true)
        }
    }
}

The important point is when they ask the view height, they subtract the keyboard height and they check of the text view is inside that area. 重要的是,当他们询问视图高度时,他们减去键盘高度,然后检查文本视图是否在该区域内。
This calculation may change in relation with your view hierarchy, this is becaus ea frame is the the position of a view respect its superview, thus if your rect is inside another view, you need to convert its frame to obtain which is its frame related to the main view. 此计算可能会随您的视图层次结构而变化,因为这是因为框架是视图相对于其超级视图的位置,因此,如果您的rect在另一个视图内,则需要转换其框架以获得与之相关的框架主要观点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM