如何使用应用内自定义键盘的按钮输入文本
Posted
技术标签:
【中文标题】如何使用应用内自定义键盘的按钮输入文本【英文标题】:How to input text using the buttons of an in-app custom keyboard 【发布时间】:2016-02-03 12:30:42 【问题描述】:我制作了一个应用内自定义键盘,它取代了系统键盘,并在我点击 UITextField
时弹出。
这是我的代码:
class ViewController: UIViewController
var myCustomKeyboard: UIView!
@IBOutlet weak var textField: UITextField!
override func viewDidLoad()
super.viewDidLoad()
let keyboardNib = UINib(nibName: "Keyboard", bundle: nil)
myCustomKeyboard = keyboardNib.instantiateWithOwner(self, options: nil)[0] as! UIView
textField.inputView = myCustomKeyboard
键盘布局是从 xib 文件加载的。
问题
如何将按钮文本放入文本字段?
注意事项:
有很多关于制作自定义系统键盘的教程(需要安装),但我只想要一个应用内键盘。教程使用了专门的键盘视图控制器,但在这里我似乎只是在设置键盘视图。 我已阅读Custom Views for Data Input 文档。 This 是我能找到的最接近的 Stack Overflow 问题,但它并没有描述如何从按钮中获取文本。更新
This tutorial 似乎表明自定义输入视图有一个视图控制器。但是,我迷失在 Objective-C 代码中。 Swift 中的流程是什么? This answer 提到了UITextField
符合的UIKeyInput
协议,但是我该如何使用呢?
如果有任何内置方式也可以制作自定义应用内键盘,我真的更喜欢制作普通的自定义视图。
【问题讨论】:
只需将按钮标题附加到文本字段:textField.text = textField.text+button.title
?
由于按钮存储在 xib 文件中,我如何获得对它们的引用?
您可以为您的键盘创建一个自定义视图子类并公开按钮,或者更好地实现一个委托。或者,如果您想保留您的 xib,请在您的 xib 中为您的按钮添加一个标签。然后使用myCustomKeyboard.viewWithTag(tag)
访问它们
感谢这些想法。我可能最终会选择类似的东西。但是,对于系统键盘,视图控制器不需要知道有关键盘上的按钮的任何信息。它只接受其中的文本。应用内自定义键盘没有类似的东西吗?
我不这么认为。您必须自己管理键盘行为,因为它只是一个自定义视图。
【参考方案1】:
我想像这样:
处理按钮事件的新函数
func updateTextfield(sender: UIButton)
textField.text = (textField.text ?? "") + (sender.titleForState(.Normal) ?? "")
在初始化您的自定义键盘后,注册按钮:
myCustomKeyboard.subviews
.filter $0 as? UIButton != nil // Keep the buttons only
.forEach ($0 as! UIButton).addTarget(self, action: "updateTextfield", forControlEvents: .TouchUpInside)
【讨论】:
【参考方案2】:设置
制作一个包含所有密钥的xib
文件
使用自动布局,这样无论以后将键盘设置为多大,按键都会调整到正确的比例。
创建一个与xib
文件同名的swift
文件,并在xib
文件设置中将其设置为文件所有者。
将所有关键按钮连接到 swift
文件中的 IBAction 方法。 (参见下面的代码。)
代码
我正在使用delegate pattern 在自定义键盘视图和主视图控制器之间进行通信。这允许它们被解耦。无需更改主视图控制器中的详细实现代码即可换入和换出多个不同的自定义键盘。
Keyboard.swift
文件
import UIKit
protocol KeyboardDelegate
func keyWasTapped(character: String)
class Keyboard: UIView
var delegate: KeyboardDelegate?
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 extention not needed
let view = NSBundle.mainBundle().loadNibNamed(xibFileName, owner: self, options: nil)[0] as! UIView
self.addSubview(view)
view.frame = self.bounds
@IBAction func keyTapped(sender: UIButton)
self.delegate?.keyWasTapped(sender.titleLabel!.text!)
主视图控制器
请注意,ViewController
符合我们创建的 KeyboardDelegate
协议。此外,在创建键盘视图的实例时,需要设置height
,但不需要设置width
。显然设置文本字段的inputView
会将键盘视图宽度更新为屏幕宽度,这很方便。
class ViewController: UIViewController, KeyboardDelegate
@IBOutlet weak var textField: UITextField!
override func viewDidLoad()
super.viewDidLoad()
// get an instance of the Keyboard (only the height is important)
let keyboardView = Keyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 300))
// use the delegate to communicate
keyboardView.delegate = self
// replace the system keyboard with the custom keyboard
textField.inputView = keyboardView
// required method for keyboard delegate protocol
func keyWasTapped(character: String)
textField.insertText(character)
来源
@ryancrunchi's comment 中的建议很有帮助。 This answer 来自Creating a reusable UIView with xib (and loading from storyboard)相关
A Swift example of Custom Views for Data Input (custom in-app keyboard)【讨论】:
你对这个解决方案完全正确:)。只是一点点:Set up the xib metrics as follows
不会影响运行应用程序时视图的呈现方式。它只是在界面生成器中进行模拟,以查看 would
在设置指标时如何呈现。
啊,不知怎的,我错过了“模拟”这个词的意义。感谢您指出了这一点。我从答案中删除了该步骤。
实施完成。但是当我单击按钮时,它不会在textfiled
中插入文本。它没有到 keyWasTapped
@Piraba,我只能猜测您的代理配置不正确,或者您可能忘记将 IBAction 连接到按键。添加一些print
语句或在调试模式下逐步检查所有内容以查看问题所在。另见this answer。如果不是这些,那么我建议您提出一个新问题并提供更多详细信息。
@Suragch 当我单击数字时,它会在“keyTapped”方法中打印一些文本。但是在viewController类中没有。我也实现了keyboarddelegate协议以上是关于如何使用应用内自定义键盘的按钮输入文本的主要内容,如果未能解决你的问题,请参考以下文章
Android IME:显示一个自定义弹出对话框(如 Swype 键盘),可以在 TextView 中输入文本