简体   繁体   English

在点击UITextField时,加载nib文件以充当自定义键盘

[英]Load a nib file to act as a custom keyboard when a UITextField is tapped

I'm trying to load a .xib file to act as a custom keyboard when a textField is tapped. 我正在尝试加载.xib文件,以便在点击textField时充当自定义键盘。 I'm able to show the .xib file (view) when the textField is tapped but I'm not sure how to communicate the buttons in the .xib file with the a textField in the ViewController.swift . 我可以在点击textField时显示.xib文件(视图),但我不确定如何使用ViewController.swift中的textField传递.xib文件中的按钮。

This is what I have done so far. 这就是我到目前为止所做的。

  1. Created a single project. 创建了一个项目。

  2. Added a UITextField and created an outlet for it. 添加了UITextField并为其创建了一个插座。

     @IBOutlet weak var myField: MyTextField! 
  3. Created a new .xib file and called it CustomView.xib . 创建了一个新的.xib文件并将其命名为CustomView.xib

  4. Created a new class and called it CustomView.swift . 创建了一个新类,并将其CustomView.swift

  5. Assigned class CustomView.swift to the CustomView.xib file. 将类CustomView.swift分配给CustomView.xib文件。

  6. Added some UIButtons in the CustomView.xib file. CustomView.xib文件中添加了一些UIButtons These will be acting as a custom-keyboard, they will show when the textField is tapped and hide when the resignFirstResponder method is called. 这些将作为自定义键盘,当调用resignFirstResponder方法时,它们将在resignFirstResponder textField时显示并隐藏。

  7. In the viewDidLoad method of the ViewController.swift I assigned inputView as follow. ViewController.swiftviewDidLoad方法中,我将inputView分配如下。

      import UIKit class ViewController: UIViewController { @IBOutlet weak var myField: MyTextField! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let myView = NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, options: nil).first as? CustomView myField.inputView = myView } } 
  8. Done 完成

When I run the app and tap on the textField the .xib file shows (see picture below), my problem is, how do I communicate the buttons with the textField in the ViewController.swif . 当我运行应用程序并点击textField时,.xib文件显示(见下图),我的问题是,如何将这些按钮与ViewController.swif的textField进行通信。 In other words what I want is to show the numbers in the inputField when they are tapped. 换句话说,我想要的是在点击它们时显示inputField中的数字。

Any suggestions? 有什么建议么? Is this how this is usually done. 这是通常如何做到的。

Here is an image that shows the view shown when the inputField was tapped. 这是一个图像,显示轻触inputField时显示的视图。

在此输入图像描述

Let's say you have 9 UIButton s, then consider ctrl + dragging an IBAction from all these buttons in storyboard to a single method such as: 假设你有9个UIButton ,然后考虑ctrl +将故事板中所有这些按钮的IBAction拖动到单个方法,例如:

- (IBAction)tapped:(id)sender
{
    textView.text = [NSString stringWithFormat:@"%@%li", textView.text, (long)((UIButton*)sender).tag];
    NSLog(@"%@", textView.text);
}

given that textField is your text field, you could then append each corresponding number from your keypad (that is to say, the buttons) using the tag property of these buttons and the aforementioned method. 鉴于textField是您的文本字段,您可以使用这些按钮的tag属性和上述方法从键盘(也就是按钮)附加每个相应的数字。

You could set the tag number for each single button in storyboard (Ie, 1 - 9, respectively). 您可以为故事板中的每个按钮设置标签号(即,分别为1 - 9)。

I didn't test it using 9 buttons but did with only 2, with tag numbers 1 and 2, respectively for each buttons. 我没有使用9个按钮进行测试,但只使用了2个按钮,标签编号分别为1和2,每个按钮。 The result was displaying fine in UITextField (Ie, 1 , 12 , 122 and so forth). 结果被显示在细UITextField (即, 112122等)。

Update (Post-comment): 更新(评论后):

I was able to re-create this using a nib file containing a few buttons and a UITextField in storyboard . 我能够使用包含几个按钮和故事板中UITextFieldnib文件重新创建它。

The process proceeds as follows: 该过程如下:

1. Create a nib with all the buttons (which you already have done). 1.使用所有按钮(您已经完成)创建一个笔尖。

2. Create a view; 2.创建一个视图; and under "Custom Class", re-name the class to this view (Ie, "Custom Class" -> "Class" -> "view-that-holds-the-buttons"). 在“自定义类”下,将类重命名为此视图(即“自定义类” - >“类” - >“视图 - 按住按钮”)。

3. Wire the IBAction s (a total of 9 corresponding to the number of your buttons) to one single method as described above. 3.IBAction S作为如上所述的一个单一的方法(对应于您的按钮的数量共计9)。

4. In your other view controller whose view hold the UITextField , load the nib using your existing method. 4.在其视图中包含UITextField其他视图控制器中,使用现有方法加载nib。

5. Add this view (from nib) as subview. 5.将此视图(来自nib)添加为子视图。

The following concerns with communication between the view (that holds the buttons along with the IBAction method) and the controller in which you load the nib : 以下涉及视图(包含按钮和IBAction方法)与加载nib的控制器之间的通信:

6. create a delegate ( weak ) property. 6.创建delegateweak )属性。

7. Before you add the view (from nib ), assign this delegate with the view controller (the control that loads the nib ). 7.在添加视图(从nib )之前,使用视图控制器(加载nib的控件)分配此delegate

8. Create a protocol: 8.创建协议:

For instance: 例如:

protocol keypadProtocol : class
{
    func displayKeys(keystrokeObject: AnyObject)
}

Have the view controller that loads the nib conform to this protocol and implement the required method ( displayKeys ): 让加载nib的视图控制器符合此协议并实现所需的方法( displayKeys ):

//The one that loads the nib, which also holds the UITextField
class mainViewController: UIViewController, keypadProtocol

So, once the buttons are tapped, the IBAction would be called; 因此,一旦按下按钮,就会调用IBAction ; but instead of displaying it, we send the sender to our delegate , which is the view controller that implements the displayKeys method and holds the UITextField . 但是我们不是显示它,而是将发送sender给我们的delegatedelegate是实现displayKeys方法并保存UITextField的视图控制器。

The IBAction would be implemented as follows: IBAction将实施如下:

@IBAction func tapped(sender: AnyObject)
{
     delegate!.displayKeys(sender)
}

displayKeys would be implemented like the following: displayKeys将实现如下:

func displayKeys(keystrokeObject: AnyObject)
{
    textView.text = NSString(format: "%@%li", textView.text! ?? "", (keystrokeObject as! UIButton).tag) as String
}

Declaration of the delegate in the controller where you load the nib file: 在加载nib文件的控制器中声明delegate

weak var delegate : keypadProtocol?

Assigning the delegate from within the view controller where you load the nib : 分配的delegate从这里装载的视图控制器内的nib

keyPadView.delegate = self //keyPadView is the nib file loaded

In reply to your second comment: 回复你的第二条评论:

Assumption: 假设:

We have 2 classes. 我们有2个班级。

The first one is a subclass of UIView , which is the xib , that holds the buttons. 第一个是UIView的子类,它是xib ,用于保存按钮。 Let's call this „KeypadView“. 我们称之为“KeypadView”。

The second one is the main view controller, which is associated to the controller that holds the UITextField in your storyboard. 第二个是主视图控制器,它与控制器相关联,该控制器将故事板中的UITextField保存在其中。 Let's call this „MainViewController“. 我们称之为“MainViewController”。

Step 2: 第2步:

Firstly, please create a new UIView and name it, for the sake of consistency, „KeypadView“. 首先,为了保持一致性,请创建一个新的UIView并命名为“KeypadView”。
Then, click on your .xib file; 然后,单击.xib文件; on the right panel, click on the third tab from the left, which is called „ Identity Inspector “; 在右侧面板上,单击左侧的第三个选项卡,称为“ Identity Inspector ”; you would see „ Custom Class -> Class “, where you would associate this xib to the class you created (you need this class, in order to connect the IBAction for the buttons from the xib file to it). 你会看到“ 自定义类 - >类 ”,你可以将这个xib与你创建的类相关联(你需要这个类,以便将xib文件中的按钮的IBAction连接到它)。 It would be the „KeypadView“, which is a subclass of UIView . 它将是“KeypadView”,它是UIView的子类。

Step 6: 第6步:

You declare this in the class („KeypadView“) that holds the buttons. 您在包含按钮的类(“KeypadView”)中声明了这一点。

Step 8: 第8步:

You connect this method ( IBAction ) to the aforementioned class (Ie, „KeypadView“). 您将此方法( IBAction )连接到上述类(即“KeypadView”)。

Once you load the xib („KeypadView“) from within the „mainViewController“, set the delegate in „KeypadView“ to self ( self is the „MainViewController“): 从“mainViewController”中加载xib (“KeypadView”)后,将“KeypadView”中的delegate设置为selfself是“MainViewController”):

let keyPadView = NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, options: nil).first as? KeyPadView

keyPadView.delegate = self
self.view.addSubview(keypadView)

//you may need to re-adjust the position of the views; I will leave that to you

In your „KeyPadView“ class, there should be an IBAction that gets called from each of the buttons: 在“KeyPadView”类中,应该有一个从每个按钮调用的IBAction

Ie, 也就是说,

@IBAction func tapped(sender: AnyObject)
{
    delegate!.displayKeys(sender)
}

Our delegate is the „mainViewController“, if you recall. 如果你还记得,我们的delegate是“mainViewController”。

Since displayKeys is implemented in „mainViewController“, the following method would be called therein: 由于displayKeys在“mainViewController”中实现,因此将调用以下方法:

func displayKeys(keystrokeObject: AnyObject)
{
    textView.text = NSString(format: "%@%li", textView.text! ?? "", (keystrokeObject as! UIButton).tag) as String
}

„mainViewController“ would then display the keystrokes in its UITextField (Ie, textView ). “mainViewController”将然后显示在它的键击UITextField (即, textView )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM