使用“滚动视图”移动视图以防止键盘模糊文本字段或文本视图

时间:2018-03-12 22:52:04

标签: swift keyboard textview scrollview textfield

我正在实施一个应用程序,点按一个按钮会弹出一个位置输入屏幕,该屏幕通过模态显示的Segue 带有模糊的视觉效果实现,以进入输入窗口出现悬停在主屏幕上方。

弹出屏幕包含位置名称的文本字段和备注的多行文本视图。

问题是在较小的设备和横向视图中,多行文本视图被键盘部分遮挡。

Landscape View

Portrait View

Modal Segue View

我试图利用这里描述的解决方案,它应该利用滚动视图在键盘出现时移动视图,但它似乎不适用于我的项目:Move a view up only when the keyboard covers an input field

这个问题没有回答我的问题,因为我的文字字段和视图位于另一个视图中,使其显示为主屏幕的弹出窗口:Move a view up only when the keyboard covers an input field

为了实现弹出视图(在模态segue中),我将文本字段和视图放在视图中,该视图位于滚动视图内,这是位于带有模糊视图的视觉效果的视图内。

我遇到的另一个问题是我在文本字段/视图外部点击时执行以下代码来解除键盘,但由于某种原因它似乎无法正常工作

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
    self.view.endEditing(true)

}

以下是Xcode 9.2中弹出视图的View Controller的代码 项目档案:Xcode Project Archive

//
//  LocationEntryScrollViewController.swift
//

import UIKit

class LocationEntryScrollViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate {

    @IBOutlet weak var ScrollView: UIScrollView!
    @IBOutlet weak var LocationEntryView: UIView!
    @IBOutlet weak var LocationTextField: UITextField!
    @IBOutlet weak var RemarksTextView: UITextView!

    var activeTextField: UITextField?
    var activeTextView: UITextView?

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

        LocationEntryView.layer.cornerRadius = 10
        LocationEntryView.layer.masksToBounds = true

        LocationTextField.delegate = self   // dismiss keyboard when tapped outside keyboard
        RemarksTextView.delegate = self   // dismiss keyboard when tapped outside keyboard
    }

    override func viewDidAppear(_ animated: Bool)
    {
        super.viewDidAppear(animated)
        LocationTextField.becomeFirstResponder()
        RemarksTextView.becomeFirstResponder()
    }

    /**
     * Called when the user click on the view (outside the UITextField).
     */
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
    {
        self.view.endEditing(true)

    }

    override func viewDidDisappear(_ animated: Bool)
    {
        deregisterFromKeyboardNotifications()
    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func DoneButtonTapped(_ sender: Any)
    {
        dismiss(animated: true, completion: nil)
    }

    @IBAction func CancelButtonTapped(_ sender: Any)
    {
    }

    @objc func keyboardWasShown(notification: NSNotification)
    {
        //Need to calculate keyboard exact size due to Apple suggestions
        self.ScrollView.isScrollEnabled = true
        var info = 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 let activeTextField = self.activeTextField
        {
            if (!aRect.contains(activeTextField.frame.origin))
            {
                self.ScrollView.scrollRectToVisible(activeTextField.frame, animated: true)
            }
        }

        if let activeTextView = self.activeTextView
        {
            if (!aRect.contains(activeTextView.frame.origin))
            {
                self.ScrollView.scrollRectToVisible(activeTextView.frame, animated: true)
            }
        }
    }

    @objc func keyboardWillBeHidden(notification: NSNotification)
    {
        //Once keyboard disappears, restore original positions
        let info : NSDictionary = notification.userInfo! as NSDictionary
        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
        self.view.endEditing(true)
        self.ScrollView.isScrollEnabled = false

    }

    func textFieldDidBeginEditing(_ textField: UITextField)
    {
        activeTextField = textField
    }


    func textFieldDidEndEditing(_ textField: UITextField)
    {
        activeTextField = nil
    }

    func textViewDidBeginEditing(_ textView: UITextView)
    {
        activeTextView = textView
    }

    func textViewDidEndEditing(_ textView: UITextView) {
        activeTextView = nil
    }

    func registerForKeyboardNotifications()
    {
        //Adding notifies on keyboard appearing
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    func deregisterFromKeyboardNotifications()
    {
        //Removing notifies on keyboard appearing
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }
}

0 个答案:

没有答案