创建自定义应用内键盘
http://i.stack.imgur.com/10lPa.gif
这是一个基本的应用内键盘。可以使用相同的方法来制作任何键盘布局。以下是需要完成的主要工作:
- 在 .xib 文件中创建键盘布局,该文件的所有者是 Swift 或 Objective-C 类,它是
UIView
的子类。 - 告诉
UITextField
使用自定义键盘。 - 使用委托在键盘和主视图控制器之间进行通信。
创建 .xib 键盘布局文件
- 在 Xcode 中,转到文件>新建>文件…> iOS>用户界面>视图以创建 .xib 文件。
- 我调用我的 Keyboard.xib
- 添加所需的按钮。
- 使用自动布局约束,这样无论键盘的大小如何,按钮都会相应调整大小。
- 将文件所有者(不是根视图)设置为
Keyboard
类。这是一个常见的错误来源。你将在下一步中创建此类。请参阅最后的注释。
创建 .swift UIView 子类键盘文件
-
在 Xcode 中,转到 File> New> File …> iOS> Source> Cocoa Touch Class 来创建 Swift 或 Objective-C 类。选择
UIView
作为新创建的类的超类 -
我调用我的
Keyboard.swift
(Objective-C 中的Keyboard
类) -
为 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 = NSBundle.mainBundle().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(sender.titleLabel!.text!) // could alternatively send a tag value } }
-
为 Objective-C 添加以下代码:
Keyboard.h 文件
#import <UIKit/UIKit.h> // The view controller will adopt this protocol (delegate) // and thus must contain the keyWasTapped method @protocol KeyboardDelegate<NSObject> - (void)keyWasTapped:(NSString *)character; @end @interface Keyboard : UIView @property (nonatomic, weak) id<KeyboardDelegate> delegate; @end
Keyboard.m 文件
#import "Keyboard.h" @implementation Keyboard - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; [self initializeSubviews]; return self; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; [self initializeSubviews]; return self; } - (void)initializeSubviews { NSString *xibFileName = @"Keyboard"; // xib extention not included UIView *view = [[[NSBundle mainBundle] loadNibNamed:xibFileName owner:self options:nil] firstObject]; [self addSubview:view]; view.frame = self.bounds; } // MARK:- Button actions from .xib file -(IBAction)keyTapped:(UIButton *)sender { // When a button is tapped, send that information to the // delegate (ie, the view controller) [self.delegate keyWasTapped:sender.titleLabel.text]; // could alternatively send a tag value } @end
-
控制从 .xib 文件中的按钮到按钮回调的拖动操作到 Swift 或 Objective-C 所有者中的
@IBAction
方法,以将它们全部挂起。 -
请注意协议和委托代码。有关代表如何工作的简单说明,请参阅此答案 。
设置视图控制器
-
将
UITextField
添加到主故事板并使用IBOutlet
将其连接到视图控制器。叫它textField
。 -
在 Swift 中对 View Controller 使用以下代码:
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) } }
-
对 Objective-C 使用以下代码:
.h 文件
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @end
.m 文件
#import "ViewController.h" #import "Keyboard.h" @interface ViewController ()<KeyboardDelegate> @property (nonatomic, weak) IBOutlet UITextField *textField; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // initialize custom keyboard Keyboard *keyboardView = [[Keyboard alloc] initWithFrame:CGRectMake(0, 0, 0, 300)]; keyboardView.delegate = self; // the view controller will be notified by the keyboard whenever a key is tapped // replace system keyboard with custom keyboard self.textField.inputView = keyboardView; } - (void)keyWasTapped:(NSString *)character { [self.textField insertText:character]; } @end
-
请注意,视图控制器采用我们在上面定义的
KeyboardDelegate
协议。
常见错误
如果你收到 EXC_BAD_ACCESS
错误,可能是因为你将视图的自定义类设置为 Keyboard
而不是为 nib 文件的所有者执行此操作。
选择 Keyboard.nib
,然后选择 File’s Owner。
确保根视图的自定义类为空。
笔记
此示例最初来自此 Stack Overflow 答案 。