Swift 中的自定义输入视图

Posted

技术标签:

【中文标题】Swift 中的自定义输入视图【英文标题】:Custom Input View in Swift 【发布时间】:2014-10-28 05:13:39 【问题描述】:

我花了几个小时试图弄清楚如何创建/然后让自定义inputView 工作。 我有一个TextInputs 网格(想想拼字游戏板),按下时应该加载自定义inputView 以插入文本。

我为自定义inputView 创建了一个包含UI elements.xib 文件。我能够创建一个CustomInputViewController 并让inputView 出现,但永远无法获得实际的TextInput 来更新它的值/文本

Apple 文档似乎对如何使其工作很清楚,而且我见过的许多教程都在使用 Obj-C(由于现在似乎无法完成的小事情,我无法转换它迅速)。

为多个textInputs(委托链、控制器、.xib、视图等)创建customInputView 应实现的总体架构和必要的代码片段是什么?

【问题讨论】:

创建一个自定义类文件并将其设置为 InterfaceBuilder 中 xib 的类。然后你可以从 UI 元素 ctrl-drag 到你的类文件(助手编辑器)来创建 IBOutlets。在你的代码中使用这个 outlet 来更新 UI 元素。 我已经能够为 customView 中的按钮创建 IBOutlets/IBActions。这对于让 customView 中的按钮将 textInput/keyboardFunctionality 传达给 TextInputs 的视图是必要的,但还不够。 您的视图不需要实现/符合正确的协议吗? (UITextInput?)。您可能还必须告诉他们在被点击时成为第一响应者。我会尝试继承 UIControl 与 UIView 看看这个:***.com/questions/26539849/…. 【参考方案1】:

使用适当的 inputView 布局和项目设置一个 nib 文件。就我而言,我将每个按钮设置为对 inputViewButtonPressed 的文件所有者的操作。

为视图控制器设置故事板(或 nib,如果您愿意)。

然后使用下面的代码,你应该得到你要找的东西:

class ViewController: UIViewController, UITextFieldDelegate 
    var myInputView : UIView!
    var activeTextField : UITextField?

    override func viewDidLoad() 
        super.viewDidLoad()

        // load input view from nib
        if let objects = NSBundle.mainBundle().loadNibNamed("InputView", owner: self, options: nil) 
            myInputView = objects[0] as UIView
        

        // Set up all the text fields with us as the delegate and
        // using our input view
        for view in self.view.subviews 
            if let textField = view as? UITextField 
                textField.inputView = myInputView
                textField.delegate = self
            
        
    

    func textFieldDidBeginEditing(textField: UITextField) 
        activeTextField = textField
    

    func textFieldDidEndEditing(textField: UITextField) 
        activeTextField = nil
    

    @IBAction func inputViewButtonPressed(button:UIButton) 
        // Update the text field with the text from the button pressed
        activeTextField?.text = button.titleLabel?.text

        // Close the text field
        activeTextField?.resignFirstResponder()
    

或者,如果您想要更像键盘,您可以将此函数用作您的操作(它使用 Swift 1.2 中的新 let 语法),如果您需要 1.1 兼容性,请将其拆分:

    @IBAction func insertButtonText(button:UIButton) 
        if let textField = activeTextField, title = button.titleLabel?.text, range = textField.selectedTextRange 
            // Update the text field with the text from the button pressed
            textField.replaceRange(range, withText: title)
        
    

这使用UITextInput 协议来适当地更新文本字段。处理删除有点复杂,但还不错:

    @IBAction func deleteText(button:UIButton) 
        if let textField = activeTextField, range = textField.selectedTextRange 
            if range.empty 
                // If the selection is empty, delete the character behind the cursor
                let start = textField.positionFromPosition(range.start, inDirection: .Left, offset: 1)
                let deleteRange = textField.textRangeFromPosition(start, toPosition: range.end)
                textField.replaceRange(deleteRange, withText: "")
            
            else 
                // If the selection isn't empty, delete the chars in the selection
                textField.replaceRange(range, withText: "")
            
        
    

【讨论】:

非常感谢大卫的回答。如果我想在几个地方重复使用键盘,你会推荐什么作为最好的方法? 你可以继承 UIViewController 或者你可以在 UITextField 子类或单独的控制器类中实例化这段代码。【参考方案2】:

您不应该经历所有这些麻烦。 ios 8 中有一个新类,名为:UIAlertController,您可以在其中添加 TextFields 供用户输入数据。您可以将其设置为警报或操作表。

例子:

let alertAnswer = UIAlertController(title: "Input your scrabble Answer", message: nil, preferredStyle: .Alert) // or .ActionSheet

现在你有了控制器,给它添加字段:

alertAnswer.addTextFieldWithConfigurationHandler  (get) -> Void in
            getAnswer.placeholder = "Answer"
            getAnswer.keyboardType = .Default
            getAnswer.clearsOnBeginEditing = true
            getAnswer.borderStyle = .RoundedRect
         // add as many fields as you want with custom tweaks

添加操作按钮:

let submitAnswer = UIAlertAction(title: "Submit", style: .Default, handler: nil)
let cancel = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
alertAnswer.addAction(submitAnswer)
alertAnswer.addAction(cancel)

随时展示控制器:

self.presentViewController(alertAnswer, animated: true, completion: nil)

如您所见,您有各种处理程序可以在任何步骤传递自定义代码。

例如,它的外观如下:

【讨论】:

以上是关于Swift 中的自定义输入视图的主要内容,如果未能解决你的问题,请参考以下文章

iOS swift中的自定义视图出口在视图控制器中不起作用

swift中的自定义集合视图单元格

Swift:嵌入在导航控制器中的视图之间的自定义segue

从 Swift 中的自定义数据单元开始

单击Swift 4中的自定义按钮时调整单元格大小

从 Swift 中的自定义相机拍摄后裁剪图像