Ios 用于数据输入的自定义视图的Swift示例(自定义应用程序内键盘) 目标
我想制作一个只在我的应用程序中使用的自定义键盘,而不是需要安装的系统键盘 我读过并尝试过的东西 文档Ios 用于数据输入的自定义视图的Swift示例(自定义应用程序内键盘) 目标,ios,swift,keyboard,custom-keyboard,Ios,Swift,Keyboard,Custom Keyboard,我想制作一个只在我的应用程序中使用的自定义键盘,而不是需要安装的系统键盘 我读过并尝试过的东西 文档 上述第一条规定: 确保定制的全系统键盘确实是您想要的 发展为您的应用程序提供完全定制的键盘,或 仅在应用程序中使用自定义键补充系统键盘 iOS SDK提供了其他更好的选项。了解自定义输入视图 并在自定义视图中输入附件视图,以便在文本中输入数据 iOS编程指南 这就是我读到上面第二篇文章的原因。然而,那篇文章没有足够的细节让我开始 教程 我能够从上面列表中的第二个教程中获得一个
- 在.xib文件中创建键盘布局,其所有者是包含
子类的.swift文件UIView
- 告诉
使用自定义键盘UITextField
- 使用代理在键盘和主视图控制器之间进行通信
- 在Xcode中转到文件>新建>文件…>iOS>用户界面>查看以创建.xib文件
- 我叫我的键盘.xib
- 添加您需要的按钮
- 使用自动布局约束,以便无论键盘大小如何,按钮都将相应调整大小
- 将文件的所有者(不是根视图)设置为Keyboard.swift文件。这是常见的错误源。见最后的注释
- 在Xcode中转到文件>新建>文件…>iOS>Source>Cocoa Touch类创建.swift文件
- 我打电话给我的键盘。斯威夫特
- 添加以下代码:
import UIKit // The view controller will adopt this protocol (delegate) // and thus must contain the keyWasTapped method protocol KeyboardDelegate: class { func keyWasTapped(character: String) } class Keyboard: UIView { // This variable will be set as the view controller so that // the keyboard can send messages to the view controller. weak var delegate: KeyboardDelegate? // MARK:- keyboard initialization 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 included let view = Bundle.main.loadNibNamed(xibFileName, owner: self, options: nil)![0] as! UIView self.addSubview(view) view.frame = self.bounds } // MARK:- Button actions from .xib file @IBAction func keyTapped(sender: UIButton) { // When a button is tapped, send that information to the // delegate (ie, the view controller) self.delegate?.keyWasTapped(character: sender.titleLabel!.text!) // could alternatively send a tag value } }
- 控制从.xib文件中的按钮拖动到.swift文件中的
方法,将它们全部连接起来@IBAction
- 请注意,协议和委托代码。有关代理如何工作的简单说明,请参见
- 将
添加到主情节提要,并使用UITextField
将其连接到视图控制器。称之为IBOutlet
textField
- 对视图控制器使用以下代码:
import UIKit class ViewController: UIViewController, KeyboardDelegate { @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() // initialize custom keyboard let keyboardView = Keyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 300)) keyboardView.delegate = self // the view controller will be notified by the keyboard whenever a key is tapped // replace system keyboard with custom keyboard textField.inputView = keyboardView } // required method for keyboard delegate protocol func keyWasTapped(character: String) { textField.insertText(character) } }
- 请注意,视图控制器采用了我们上面定义的
协议KeyboardDelegate
根据苏拉奇的回答,我需要一个“完成”和“退格”按钮,如果你是像我这样的傻瓜,这里有一些你可能会遇到的错误以及我解决这些错误的方法 获取EXC\u错误\u访问错误? 我包括:
@objc(classname)
class classname: UIView{
}
修复了我的问题,但是Suragch的更新答案似乎以更合适/正确的方式解决了这个问题
获取SIGABRT错误?
另一件愚蠢的事情是以错误的方式拖动连接,导致SIGABRT错误。不要从函数拖动到按钮,而是将按钮拖动到函数
添加完成按钮
我在keyboard.swift中将此添加到协议中:
protocol KeyboardDelegate: class {
func keyWasTapped(character: String)
func keyDone()
}
然后将一个新iAction从“我的完成”按钮连接到键盘。如下所示:
@IBAction func Done(sender: UIButton) {
self.delegate?.keyDone()
}
然后跳回我的viewController.swift,在这里我使用这个键盘,并在点击功能键后添加了以下内容:
func keyDone() {
view.endEditing(true)
}
添加退格
这让我大吃一惊,因为必须在viewDidLoad()方法(稍后显示)中将textField.delegate设置为self
首先:在keyboard.swift中添加到协议func backspace():
第二:连接一个新的iAction,类似于已完成的操作:
@IBAction func backspace(sender: UIButton) {
self.delegate?.backspace()
}
第三:转到viewController.swift,其中出现了NumberPad
重要提示:在viewDidLoad()中,设置将使用此键盘的所有文本字段。因此,您的viewDidLoad()应该如下所示:
override func viewDidLoad() {
super.viewDidLoad()
self.myTextField1.delegate = self
self.myTextField2.delegate = self
// initialize custom keyboard
let keyboardView = keyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 240))
keyboardView.delegate = self // the view controller will be notified by the keyboard whenever a key is tapped
// replace system keyboard with custom keyboard
myTextField1.inputView = keyboardView
myTextField2.inputView = keyboardView
}
var activeTextField = UITextField()
func textFieldDidBeginEditing(textField: UITextField) {
print("Setting Active Textfield")
self.activeTextField = textField
print("Active textField Set!")
}
func backspace() {
print("backspaced!")
activeTextField.deleteBackward()
}
我不知道如何,如果有一种方法可以对视图中的所有文本字段执行此操作的话。这会很方便
第四:仍然在viewController.swift中,我们需要添加一个变量和两个函数。它将如下所示:
override func viewDidLoad() {
super.viewDidLoad()
self.myTextField1.delegate = self
self.myTextField2.delegate = self
// initialize custom keyboard
let keyboardView = keyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 240))
keyboardView.delegate = self // the view controller will be notified by the keyboard whenever a key is tapped
// replace system keyboard with custom keyboard
myTextField1.inputView = keyboardView
myTextField2.inputView = keyboardView
}
var activeTextField = UITextField()
func textFieldDidBeginEditing(textField: UITextField) {
print("Setting Active Textfield")
self.activeTextField = textField
print("Active textField Set!")
}
func backspace() {
print("backspaced!")
activeTextField.deleteBackward()
}
解释此处发生的情况:
非常感谢Suragchs帮助我实现这一点。关键是使用现有的协议,
UITextField
已经符合该协议。然后您的键盘视图需要
textField.inputView = NumericKeyboard(target: textField)
textField.inputView = NumericKeyboard(target: textField, useDecimalSeparator: true)