【问题标题】:Move view when a specific textfield is selected swift快速选择特定文本字段时移动视图
【发布时间】:2017-12-14 00:15:02
【问题描述】:

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

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

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

【问题讨论】:

    标签: ios swift viewwilldisappear


    【解决方案1】:

    你可以试试这个

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

    【讨论】:

    • 如果我在 iPhone 4s 上运行该应用程序。如果视图未与视图中心对齐,我确信 topTextField 也会隐藏在键盘下。那么你将如何解决它。
    • 我使用 TPKeyboard,所以我不担心这些键盘之类的东西。但这是所问问题的答案
    • 伙计,我是在说问题本身。
    • 被问到的问题是“我怎样才能将此功能仅分配给底部文本字段”。请检查一下
    • 哥们明白了
    【解决方案2】:

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

    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
    }
    

    【讨论】:

    • 谢谢。如果没有滚动视图,我将如何实现这一点?我只想将我写的功能分配给底部的文本字段。
    • 是否可以创建一个委托文件并且只在底部文本字段的委托中包含该功能?
    • 嗯,这不起作用,但它确实让我想知道是否可以在这些方法之一中使用 if 语句来确保仅在按下 bottomText 文本字段时调用此功能。那可能吗?我会在哪里尝试呢?
    • 我认为您不必在任何地方为键盘事件编写任何代码。请做一件事删除所有移动文本字段的代码。然后安装 pod 并在 appDelegate 中写入这两行代码。这肯定会奏效。
    【解决方案3】:

    不使用外部框架的方法:

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

    步骤:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-29
        • 2014-10-30
        • 1970-01-01
        • 2013-05-14
        • 2016-06-02
        • 1970-01-01
        • 2016-05-07
        相关资源
        最近更新 更多