选择特定文本字段时移动视图 swift

Move view when a specific textfield is selected swift

我创建了一个模因生成器应用程序以更好地学习 Swift 和 Xcode。我正在学习在用户与会被键盘遮挡的文本字段交互时移动视图。我可以使用此功能,但有一个例外。所需的功能是在用户为底部文本字段输入文本时让视图向上滑动,从顶部开始。无论用户正在与之交互的文本字段如何,视图都会向上滑动。

如何将此功能仅分配给底部文本字段?这是我的源代码:

import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITextFieldDelegate {

    @IBOutlet weak var imagePickerView: UIImageView!
    @IBOutlet weak var cameraButton: UIBarButtonItem!
    @IBOutlet weak var topText: UITextField!
    @IBOutlet weak var bottomText: UITextField!

    let memeTextAttributes:[String:Any] = [
        NSAttributedStringKey.strokeColor.rawValue: UIColor.black,
        NSAttributedStringKey.foregroundColor.rawValue: UIColor.white,
        NSAttributedStringKey.font.rawValue: UIFont(name: "HelveticaNeue-CondensedBlack", size: 30)!,
        NSAttributedStringKey.strokeWidth.rawValue: -5.0]

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        subscribeToKeyboardNotifications()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Diable camer a button if camera ource isn't available
        cameraButton.isEnabled = UIImagePickerController.isSourceTypeAvailable(.camera)
        topText.delegate = self
        bottomText.delegate = self
        topText.textAlignment = .center
        bottomText.textAlignment = .center
        topText.defaultTextAttributes = memeTextAttributes
        bottomText.defaultTextAttributes = memeTextAttributes
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        unsubscribeFromKeyboardNotifications()
    }

    // MARK: Delegate Methods

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
            imagePickerView.image = image
            self.dismiss(animated: true, completion: nil)
        }
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        self.dismiss(animated: true, completion: nil)
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {
        textField.text = ""
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.topText.resignFirstResponder()
        self.bottomText.resignFirstResponder()
        return true
    }

    // MARK: Move the keyboard up when the bottom textfield is tapped

    @objc func keyboardWillShow(_ notification:Notification) {
        view.frame.origin.y = 0 - getKeyboardHeight(notification)
    }

    func getKeyboardHeight(_ notification:Notification) -> CGFloat {
        let userInfo = notification.userInfo
        let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue // of CGRect
        return keyboardSize.cgRectValue.height
    }

    func subscribeToKeyboardNotifications() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: .UIKeyboardWillHide, object: nil)
    }

    func unsubscribeFromKeyboardNotifications() {
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
    }

    // MARK: Move view down when keyboard is dismissed

    @objc func keyboardWillHide(_ notification: Notification) {
        view.frame.origin.y = 0
    }

    // MARK: IBActions

    @IBAction func pickAnImageFromAlbum(_ sender: Any) {
        let pickerController = UIImagePickerController()
        pickerController.delegate = self
        pickerController.sourceType = .photoLibrary
        present(pickerController, animated: true, completion: nil)
    }

    @IBAction func pickAnImageFromCamera(_ sender: Any) {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .camera
        present(imagePicker, animated: true, completion: nil)
    }
}

在滚动视图中添加视图。 使用

pod 'IQKeyboardManagerSwift'

它会自动处理。在应用程序委托中编写此代码:

 IQKeyboardManager.sharedManager().enable = true
 IQKeyboardManager.sharedManager().keyboardDistanceFromTextField = 30.0

如果你想要一个文本框:

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { 
    if textField == toptextField {
        IQKeyboardManager.sharedManager().enable = false 
    }
    else {
        IQKeyboardManager.sharedManager().enable = true
    } 
    return true
}

不使用外部框架的方法:

  1. 使用从文本字段到父视图的底部约束。
  2. 根据键盘是显示还是隐藏来调整常量值。

步骤:

  1. 创建从文本字段到父视图的底部约束。
  2. 将约束的常量设置为初始所需值
  3. 添加将约束存储为视图控制器中的 属性
  4. 观察UIKeyboardDidShow通知并获取键盘的结束帧。使用结束帧的负高度作为底部约束的常量。
  5. 同理UIKeyboardWillHide,将底部约束常数设置为原来的常数值

你可以试试这个

  //make a global textField to keep reference
var currentTappedTextField : UITextField?
//use this method to get tapped textField
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
   currentTappedTextField = textField
    return true
}
// now move view only when textfield is bottom
@objc func keyboardWillShow(_ notification:Notification) {
    if(currentTappedTextField == bottomText){
   view.frame.origin.y = 0 - getKeyboardHeight(notification)
    }
}

您只需要在 viewDidLoad 中观察键盘通知即可:

    override func viewDidLoad() {
        super.viewDidLoad()            
        NotificationCenter.default.addObserver(self,
                                           selector: #selector(keyboardWillShow(_:)),
                                           name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self,
                                           selector: #selector(keyboardWillHide),
                                           name: NSNotification.Name.UIKeyboardWillHide, object: nil)   
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

并声明选择器方法以更改您的视图约束:

@objc
func keyboardWillShow(_ notification: Notification) {
    if let keyboardHeight = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
        yourViewBottomConstraint.constant = keyboardHeight.cgRectValue.height + constantHeight
        UIView.animate(withDuration: 0.25, animations: {
            self.view.layoutIfNeeded()
        })
    }
}

@objc
func keyboardWillHide() {
    yourViewBottomConstraint.constant = constantHeight
    UIView.animate(withDuration: 0.25, animations: {
        self.view.layoutIfNeeded()
    })
}

别忘了实现 UITextFieldDelegate :

extension ViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.view.endEditing(true)
        return false
    }
}