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

时间:2017-12-13 11:26:09

标签: ios swift viewwilldisappear

我创建了一个meme生成器应用程序,以更好地学习Swift和Xcode。当用户与可能被键盘阻碍的文本字段进行交互时,我正在学习移动视图。我有这个功能,但有一个例外。当用户输入底部文本字段的文本时,所需的功能是让视图向上滑动。无论用户与哪个文本字段进行交互,视图都会向上滑动。

enter image description here

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

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)
    }
}

4 个答案:

答案 0 :(得分:2)

你可以试试这个

  //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)
    }
}

答案 1 :(得分:1)

在scrollview中添加视图。 使用

pod 'IQKeyboardManagerSwift'

它会自动处理。在app delegate中写下这段代码:

 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
}

答案 2 :(得分:1)

不使用外部框架的方法:

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

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

答案 3 :(得分:0)

您只需在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
    }
}