美文网首页IOSiOS Developer
Swift - 自定义数据输入视图(自定义 app 内部键盘)

Swift - 自定义数据输入视图(自定义 app 内部键盘)

作者: 张嘉夫 | 来源:发表于2017-01-06 18:39 被阅读335次

    这是一个基本的 app 内建键盘。相同的方法可以用来制作任意键盘布局。主要需要完成这些事:

    • 在一个 .xib 文件里创建键盘布局,owner 是一个 .swift 文件,包含一个 UIView 子类。
    • 告诉 UITextField 使用自定义键盘。
    • 使用 delegate 在键盘和主视图控制器之间通信。

    创建 .xib 键盘布局文件

    • 在 Xcode 里点击 File > New > File... > iOS > User Interface > View 来创建 .xib 文件。
    • 我把自己的称为 Keyboard.xib
    • 添加你需要的按钮。
    • 使用 auto layout constraints,这样不论键盘的大小是多少,按钮都会因此改变大小。
    • 设置 File's Owner (不是 root view)为 Keyboard.swift 文件。这里通常会出现错误。最后会讲。

    创建 .swift UIView 子类键盘文件

    • 在 Xcode 里点击 File > New > File... > iOS > Source > Cocoa Touch Class 来创建 .swift 文件。

    • 我把自己的成为 Keyboard.swift

    • 添加如下代码:

      import UIKit
      
      // view controller 会采用这个协议(delegate)
      // 这样它就必须包含 keyWasTapped 方法
      protocol KeyboardDelegate: class {
          func keyWasTapped(character: String)
      }
      
      class Keyboard: UIView {
      
          // 这个变量会被设置为 view controller 然后
          // 键盘就能给 view controller 发送消息
          weak var delegate: KeyboardDelegate?
      
          // MARK:- 键盘初始化
      
          required init?(coder aDecoder: NSCoder) {
              super.init(coder: aDecoder)
              initializeSubviews()
          }
      
          override init(frame: CGRect) {
              super.init(frame: frame)
              initializeSubviews()
          }
      
          func initializeSubviews() {
              let xibFileName = "Keyboard" // 不包括 xib 后缀名
              let view = NSBundle.mainBundle().loadNibNamed(xibFileName, owner: self, options: nil)[0] as! UIView
              self.addSubview(view)
              view.frame = self.bounds
          }
      
          // MARK:- .xib 文件里的按钮 action
      
          @IBAction func keyTapped(sender: UIButton) {
              // 按钮被按下后,发送信息给
              // delegate (也就是, 那个 view controller)
              self.delegate?.keyWasTapped(sender.titleLabel!.text!) // 也可以选择发送 tag 值
          }
      
      }
      
    • 按住 control 从 .xib 文件里的按钮拖到 .swift 文件里的 @IBAction 方法,这样就能把它们绑定在一起

    • 注意协议和 delegate 代码。看这篇答案简单解释了 delegate 是如何工作的。

    设置 View Controller

    • 添加一个 UITextField 到 main storyboard 里,然后用一个 IBOutlet 连接到你的 view controller。称它为 textField

    • 给 View Controller 使用下面的代码:
      import UIKit

      class ViewController: UIViewController, KeyboardDelegate {
      
          @IBOutlet weak var textField: UITextField!
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              // 初始化自定义键盘
              let keyboardView = Keyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 300))
              keyboardView.delegate = self // 键盘会通知视图控制器,在按下一个键的时候
      
              // 替换系统键盘为自定义键盘
              textField.inputView = keyboardView
          }
      
          // 键盘 delegate 协议必须的方法
          func keyWasTapped(character: String) {
              textField.insertText(character)
          }
      }
      
    • 注意 view controller 采用了我们在上面定义的 KeyboardDelegate 协议。

    常见错误

    如果你得到了一个 EXC_BAD_ACCESS 错误,大概是因为你设置了 view 的 custom class 为 Keyboard.swift 而不是 nib File's Owner。

    选择 Keyboard.nib 然后选择 File's Owner。

    确定 root view 的 custom class 是空的。

    相关文章

      网友评论

        本文标题:Swift - 自定义数据输入视图(自定义 app 内部键盘)

        本文链接:https://www.haomeiwen.com/subject/qqdxbttx.html