iOS 带有故事板的自定义键盘

iOS custom keyboard with storyboard

我正在尝试使用 Swift 制作一个简单的 iOS 自定义键盘扩展。默认的 UIView 不能满足我的需求,所以我阅读了 this SO 问题,我可以在 info.plist.[=18= 中使用带有 NSExtensionMainStoryboard 属性 的故事板]

不幸的是,每次打开键盘时,我都会收到以下错误

2016-01-18 18:02:56.350 Kappa Keyboard[44790:2959180] Failed to inherit CoreMedia permissions from 44787: (null)
2016-01-18 18:02:56.368 Kappa Keyboard[44790:2959138] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(
    0   CoreFoundation                      0x002f1746 __exceptionPreprocess + 182
    1   libobjc.A.dylib                     0x01d32a97 objc_exception_throw + 44
    2   CoreFoundation                      0x001a6ce1 -[__NSArrayM insertObject:atIndex:] + 881
    3   CoreFoundation                      0x001a6941 -[__NSArrayM addObject:] + 65
    4   UIKit                               0x00c7d0bd -[UIViewController _addChildViewController:performHierarchyCheck:notifyWillMove:] + 417
    5   UIKit                               0x00c968aa -[UIViewController(UIContainerViewControllerProtectedMethods) addChildViewController:] + 78
    6   UIKit                               0x01206db8 -[_UIViewServiceViewControllerOperator __createViewController:withContextToken:fbsDisplays:appearanceSerializedRepresentations:legacyAppearance:traitCollection:initialInterfaceOrientation:hostAccessibilityServerPort:canShowTextServices:replyHandler:] + 2702

堆栈跟踪继续,但这就是它的要点。

这是我所做的一切(我在一个干净的项目中尝试过)。

  1. 创建容器应用程序
  2. 创建键盘目标
  3. 添加Main.storyboard
  4. NSExtension.NSExtensionMainStoryboard: Main 添加到 info.plist
  5. Main.storyboard 的自定义 class 设置为默认值 KeyboardViewController

知道我错过了什么吗?

我也构建了一个自定义键盘应用程序。 以下是步骤:

Objective-C

  1. 创建键盘目标
  2. 在目标包中创建一个 xib 文件 (MyKeyboard.xib)
  3. 创建cocoa触摸classselectUIView(MyKeyboard.hMyKeyboard.m)
  4. 在 KeyboardViewController.m 中,导入 MyKeyboard.h
  5. 在KeyboardViewController.m里面,加上

@property (nonatomic, strong) MyKeyboard *myKeyboard;

ViewDidLoad:

self.myKeyboard = [[MyKeyboard alloc]init];
self.myKeyboard = [[[NSBundle mainBundle] loadNibName: @"MyKeyboard"
                                     owner:self option:nil] objectAtIndex:0];
self.inputView = (UIInputView *)self.myKeyboard;

Swift

  1. 创建键盘目标
  2. 在目标包中创建一个 UIView 界面(xib 文件)(MyKeyboard.xib)
  3. 创建cocoa触摸classselectUIInputView(MyKeyboard.swift)
  4. 里面KeyboardViewController.swift添加

// 这里

override func viewDidLoad() {
    super.viewDidLoad()
    // setup your keyboard
    self.myKeyboard = NSBundle.mainBundle().loadNibNamed("MyKeyboard", owner: self, options: nil)[0] as! MyKeyboard
    self.inputView = self.myKeyboard;

    // Perform custom UI setup here
    self.nextKeyboardButton = UIButton(type: .System)
    self.nextKeyboardButton.setTitle(NSLocalizedString("Next Keyboard", comment: "Title for 'Next Keyboard' button"), forState: .Normal)
    self.nextKeyboardButton.sizeToFit()
    self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false
    self.nextKeyboardButton.addTarget(self, action: "advanceToNextInputMode", forControlEvents: .TouchUpInside)

    self.myKeyboard.addSubview(self.nextKeyboardButton) // add the button to self.myKeyboard!!

    let nextKeyboardButtonLeftSideConstraint = NSLayoutConstraint(item: self.nextKeyboardButton, attribute: .Left, relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1.0, constant: 0.0)
    let nextKeyboardButtonBottomConstraint = NSLayoutConstraint(item: self.nextKeyboardButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1.0, constant: 0.0)
    self.view.addConstraints([nextKeyboardButtonLeftSideConstraint, nextKeyboardButtonBottomConstraint])
}

这是它的样子

将故事板文件添加到键盘目标。
在您的键盘目标的常规选项卡中,将 Main Interface 设为您的故事板文件,如屏幕截图所示。
第二个重要部分是确保将故事板中的 KeyboardViewController 参考视图的 class 更改为 UIInputView 而不是 UIView