【问题标题】:Add UIToolBar to all keyboards (swift)将 UIToolBar 添加到所有键盘(swift)
【发布时间】:2015-09-08 02:45:39
【问题描述】:

我正在尝试将自定义 UIToolBar 添加到我的所有键盘中,并尽可能少地重复。我目前这样做的方式需要我将代码添加到我的所有 viewDidLoads 并将每个文本字段的委托分配给我正在使用的 viewController。我曾尝试创建自己的 UIToolBar 子类,但我发现当我的“完成”和“取消”按钮的目标是自身视图时,我真的无法做到这一点。有人对创建易于重用的工具栏有任何建议吗?提前致谢。

override func viewDidLoad() {
    super.viewDidLoad()

    var toolBar = UIToolbar()
    toolBar.barStyle = UIBarStyle.Default
    toolBar.translucent = true
    toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
    var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "donePressed")
    var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelPressed")
    var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
    toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
    toolBar.userInteractionEnabled = true
    toolBar.sizeToFit()

    stateField.inputAccessoryView = toolBar
    stateField.delegate = self

【问题讨论】:

  • 子类UITextField?也许它也适用于扩展。

标签: ios swift uibarbuttonitem uitoolbar repeat


【解决方案1】:

我有一个实用程序,我已经使用了一段时间(从 Objective-C 移植到 Swift),它可以做到这一点,你可能会发现它很有用:

https://github.com/ncerezo/SwiftKeyboardAccessory

它创建一个工具栏,其中至少有一个“完成”按钮来关闭键盘,以及可选的下一个和上一个按钮。它还负责在您在文本字段外点击时关闭键盘,以及在键盘出现或消失时调整视图大小和滚动视图。 它旨在与 UITableVIew 以及 UIScrollView 一起使用。

【讨论】:

    【解决方案2】:

    感谢 Glorfindel 的建议和 ncerezo 的示例代码,我使用扩展解决了我的问题。

    extension UIViewController: UITextFieldDelegate{
        func addToolBar(textField: UITextField){
            var toolBar = UIToolbar()
            toolBar.barStyle = UIBarStyle.Default
            toolBar.translucent = true
            toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
            var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "donePressed")
            var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelPressed")
            var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
            toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
            toolBar.userInteractionEnabled = true
            toolBar.sizeToFit()
    
            textField.delegate = self
            textField.inputAccessoryView = toolBar
        }
        func donePressed(){
            view.endEditing(true)
        }
        func cancelPressed(){
            view.endEditing(true) // or do something
        }
    }
    

    虽然我仍然需要在我的所有文本字段上调用下面的代码。我觉得可能有更好的方法,而不必在每个 textField 上调用函数,但现在这绝对是更可重用的。

    override func viewDidLoad() {
        super.viewDidLoad()
        addToolBar(addressField)
    }
    

    【讨论】:

    • 添加以下行 @IBOutlet var textFields: [UITextField]!到你的 ViewController。然后转到情节提要并控制将所有文本字段拖入其中。然后执行:对于 textFields { addToolBar(textField) } 中的 textField - 比多行代码更简洁。
    【解决方案3】:

    相当于 swift 3 中的 vivian 版本:

    extension UIViewController: UITextFieldDelegate {
        func addToolBar(textField: UITextField) {
            let toolBar = UIToolbar()
            toolBar.barStyle = .default
            toolBar.isTranslucent = true
            toolBar.tintColor = UIColor(red: 76 / 255, green: 217 / 255, blue: 100 / 255, alpha: 1)
            let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(donePressed))
            let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelPressed))
            let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
            toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
    
    
            toolBar.isUserInteractionEnabled = true
            toolBar.sizeToFit()
    
            textField.delegate = self
            textField.inputAccessoryView = toolBar
        }
    
        func donePressed() {
            view.endEditing(true)
        }
    
        func cancelPressed() {
            view.endEditing(true) // or do something
        }
    }
    

    【讨论】:

    • 如果我需要在完成和取消按钮上设置图像怎么办?
    【解决方案4】:

    您可以利用响应者链使 UIToolbar 子类工作。无需更改您的视图控制器。在 Swift 3 中:

    class KeyboardAccessoryToolbar: UIToolbar {
        convenience init() {
            self.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
            self.barStyle = .default
            self.isTranslucent = true
            self.tintColor = UIColor(red: 76 / 255, green: 217 / 255, blue: 100 / 255, alpha: 1)
    
            let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.done))
            let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(self.cancel))
            let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
            self.items = [cancelButton, spaceButton, doneButton]
    
            self.isUserInteractionEnabled = true
            self.sizeToFit()
        }
    
        func done() {
            // Tell the current first responder (the current text input) to resign.
            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        }
    
        func cancel() {
            // Call "cancel" method on first object in the responder chain that implements it.
            UIApplication.shared.sendAction(#selector(cancel), to: nil, from: nil, for: nil)
        }
    }
    

    然后将以下内容添加到您的 applicationDidFinishLaunching 以将其应用于您的所有键盘:

        let accessoryView = KeyboardAccessoryToolbar()
        UITextField.appearance().inputAccessoryView = accessoryView
        UITextView.appearance().inputAccessoryView = accessoryView
    

    【讨论】:

    • 我看到的两个问题: 1. 键盘关闭似乎没有动画。 2. 视图控制器中是否有办法在按下完成按钮时接收消息并确定哪个文本字段触发了完成按钮?
    • @Jerland2 我没有看到使用这种方法的动画有任何问题,在 iOS 11.4 上测试。对于 2.,您可以将视图控制器设置为文本字段的 UITextFieldDelegate 并实现textFieldDidEndEditing 方法。
    【解决方案5】:

    对于 swift 4,你可以使用这个:-

    extension UIViewController : UITextFieldDelegate {
        func addToolBar(textField: UITextField){
            var toolBar = UIToolbar()
            toolBar.barStyle = UIBarStyle.default
            toolBar.isTranslucent = true
            toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
            var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: "donePressed")
            var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: "cancelPressed")
            var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
            toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
            toolBar.isUserInteractionEnabled = true
            toolBar.sizeToFit()
    
            textField.delegate = self
            textField.inputAccessoryView = toolBar
        }
        func donePressed(){
            view.endEditing(true)
        }
        func cancelPressed(){
            view.endEditing(true) // or do something
        }
    }
    

    使用

    override func viewDidLoad() {
          super.viewDidLoad()
          addToolBar(addressField)
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-21
      • 2010-09-24
      • 1970-01-01
      • 2015-06-13
      • 1970-01-01
      • 1970-01-01
      • 2016-12-02
      相关资源
      最近更新 更多