【问题标题】:How to add a return key on a decimal pad in Swift?如何在 Swift 中的小数点上添加返回键?
【发布时间】:2016-11-03 04:24:18
【问题描述】:

我在我的应用程序中设置了小数点,但如何关闭这个键盘?如何获得完成或返回键?我试过UIReturnKeyType.Done,但没有显示任何内容。

类似的东西

【问题讨论】:

  • 在 iPad 上,您可以将其添加到键盘顶部的栏中,但在其他设备上,您的选择有限。我会添加一个显示在它上面的按钮或构建一个自定义键盘

标签: ios swift keyboard


【解决方案1】:

这是一个使用扩展的 Swift 3 解决方案。如果您的应用程序中有多个数字 UITextField 对象,这是理想的选择,因为它可以灵活地为每个 UITextField 决定是否在 完成取消时执行自定义操作> 被点击。

//
//  UITextField+DoneCancelToolbar.swift
//

import UIKit

extension UITextField {
    func addDoneCancelToolbar(onDone: (target: Any, action: Selector)? = nil, onCancel: (target: Any, action: Selector)? = nil) {     
        let onCancel = onCancel ?? (target: self, action: #selector(cancelButtonTapped))
        let onDone = onDone ?? (target: self, action: #selector(doneButtonTapped))

        let toolbar: UIToolbar = UIToolbar()
        toolbar.barStyle = .default
        toolbar.items = [
            UIBarButtonItem(title: "Cancel", style: .plain, target: onCancel.target, action: onCancel.action),
            UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil),
            UIBarButtonItem(title: "Done", style: .done, target: onDone.target, action: onDone.action)
        ]
        toolbar.sizeToFit()

        self.inputAccessoryView = toolbar
    }

    // Default actions:  
    func doneButtonTapped() { self.resignFirstResponder() }
    func cancelButtonTapped() { self.resignFirstResponder() }
}

使用默认操作的使用示例:

//
// MyViewController.swift
//

@IBOutlet weak var myNumericTextField: UITextField! {
    didSet { myNumericTextField?.addDoneCancelToolbar() }
}

使用自定义完成操作的使用示例:

//
// MyViewController.swift
//

@IBOutlet weak var myNumericTextField: UITextField! {
    didSet { 
        myNumericTextField?.addDoneCancelToolbar(onDone: (target: self, action: #selector(doneButtonTappedForMyNumericTextField))) 
    }
}

func doneButtonTappedForMyNumericTextField() { 
    print("Done"); 
    myNumericTextField.resignFirstResponder() 
}

【讨论】:

  • 像魅力一样工作,可以轻松自定义设置区域设置按钮文本
  • 工作,但在运行时我有关于无效约束的信息(“无法同时满足约束”)并破坏其中一个。将UIToolbar() 更改为UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44)) 解决了它。
  • @oli 我可以在 viewdidLoad 中使用 myNumericTextField?.addDoneCancelToolbar(onDone: (target: myNumericTextField, action: #selector(doneButtonTappedForMyNumericTextField))) 吗?我尝试在 viewDidLoad 中使用它,但没有任何反应。你能解释一下为什么只有 didSet 函数可以做到这一点吗?谢谢。
【解决方案2】:

这个解决方案对我有用 =)

来源:https://gist.github.com/jplazcano87/8b5d3bc89c3578e45c3e

我为 UITextField 做了一个扩展,现在我可以在我想要的所有键盘上都有一个“完成栏”。

extension UITextField{

 func addDoneButtonToKeyboard(myAction:Selector?){
    let doneToolbar: UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 300, height: 40))
    doneToolbar.barStyle = UIBarStyle.default

    let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
    let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: myAction)

    var items = [UIBarButtonItem]()
    items.append(flexSpace)
    items.append(done)

    doneToolbar.items = items
    doneToolbar.sizeToFit()

    self.inputAccessoryView = doneToolbar
 }
}

我的视图控制器

class myViewController:UIViewController,UITextFieldDelegate{

  //MARK: - Outlets
  @IBOutlet weak var myTextField: UITextField!

  //MARK: - Life Cycle
  override func viewDidLoad() {
      super.viewDidLoad()
      myTextField.delegate = self

     //You can specify your own selector to be send in "myAction"
     myTextField.addDoneButtonToKeyboard(myAction:  #selector(self.myTextField.resignFirstResponder))
  }
}

【讨论】:

  • 这是迄今为止我见过的最简洁的解决方案!
  • 当我尝试添加自己的选择器时出现错误。
  • @ShadeToD 这是因为目标 self 在扩展内。您可以将目标作为参数传递并使用let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: target, action: myAction)。它对我有用。
  • 凯伦,我喜欢你的解决方案。我现在唯一的问题是键盘与输入字段重叠。出现键盘时有没有办法滚动视图? (我是 swift 新手)。谢谢!
  • @user2430797,你可以试试IQKeyboardManagerSwift。它将滚动屏幕以避免键盘覆盖输入字段。
【解决方案3】:

更新了 Swift 4.2 的 @olito 答案 对于 swift 4 选择器必须是 objc 方法,所以我们必须在扩展中添加 @objc 到我们的函数中

extension UITextField {
func addDoneCancelToolbar(onDone: (target: Any, action: Selector)? = nil, onCancel: (target: Any, action: Selector)? = nil) {
    let onCancel = onCancel ?? (target: self, action: #selector(cancelButtonTapped))
    let onDone = onDone ?? (target: self, action: #selector(doneButtonTapped))

    let toolbar: UIToolbar = UIToolbar()
    toolbar.barStyle = .default
    toolbar.items = [
        UIBarButtonItem(title: "Cancel", style: .plain, target: onCancel.target, action: onCancel.action),
        UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil),
        UIBarButtonItem(title: "Done", style: .done, target: onDone.target, action: onDone.action)
    ]
    toolbar.sizeToFit()

    self.inputAccessoryView = toolbar
}

// Default actions:
@objc func doneButtonTapped() { self.resignFirstResponder() }
@objc func cancelButtonTapped() { self.resignFirstResponder() }}

(一定要连接IBOutlet)

    @IBOutlet weak var vehicleModelTF: UITextField!

在 viewDidLoad 中,我们可以将工具栏添加到文本字段。

 myTextField.addDoneCancelToolbar(onDone: (target: self, action: #selector(self.tapDone)), onCancel: (target: self, action: #selector(self.tapCancel)))

现在我们必须添加 2 个 objc 方法。

 @objc func tapDone() {
    print("tapped Done")
}

@objc func tapCancel() {
    print("tapped cancel")
}

【讨论】:

    【解决方案4】:
    class ViewController: UIViewController {
    
        let textField = UITextField(frame: CGRect(x: 0, y: 20, width: 200, height: 60))
    
        override func viewDidLoad() {
            super.viewDidLoad()
            textField.borderStyle = .Line
            textField.inputAccessoryView = accessoryView()
            textField.inputAccessoryView?.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 44)
            view.addSubview(textField)
        }
    
        func accessoryView() -> UIView {
    
            let view = UIView()
            view.backgroundColor = UIColor.redColor()
    
            let doneButton = UIButton()
            doneButton.frame = CGRect(x: self.view.frame.width - 80, y: 7, width: 60, height: 30)
            doneButton.backgroundColor = UIColor.greenColor()
            doneButton.setTitle("done", forState: .Normal)
            doneButton.addTarget(self, action: #selector(ViewController.doneAction), forControlEvents: .TouchUpInside)
            view.addSubview(doneButton)
    
            return view
    
        }
    
        @objc func doneAction() {
            textField.resignFirstResponder()
        }
    }
    

    【讨论】:

    • 是的,因为我无法解决这个问题。我用另一种方式。
    • @AmitNivedanKalra 如果您要提供替代解决方案,您可能应该在这里解释您所做的事情......
    • 很棒,可行的解决方案
    猜你喜欢
    • 2016-06-20
    • 2015-06-13
    • 2012-07-18
    • 1970-01-01
    • 2014-07-31
    • 2023-03-15
    • 1970-01-01
    • 2014-12-03
    • 2021-12-24
    相关资源
    最近更新 更多