为 .xib 所有者的 ViewController 中的 textField 设置委托

Posted

技术标签:

【中文标题】为 .xib 所有者的 ViewController 中的 textField 设置委托【英文标题】:Set delegate for textField in ViewController that is owner of .xib 【发布时间】:2015-07-09 13:25:41 【问题描述】:

我正在尝试使用 xib 文件来显示自定义更改视图。为此,我使用来自here 的 SimpleAlert。我有一个 .xib 文件,其中包含我的 textFields,并且作为 .xib 的所有者,我设置了 ViewController 已创建。

import UIKit

class TestBaumViewController: UIViewController, UITextFieldDelegate 

@IBOutlet weak var tfFirst: UITextField!
@IBOutlet weak var tfSecond: UITextField!
@IBOutlet weak var tfThird: UITextField!
@IBOutlet weak var tfFourth: UITextField!


init() 
    super.init(nibName: "TestBaumViewController", bundle: nil)
    initializeTextFields()


required init(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)


override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    //initializeTextFields()


override func viewDidAppear(animated: Bool) 
    super.viewDidAppear(animated)
    //initializeTextFields()


override func awakeFromNib() 
    super.awakeFromNib()
    //initializeTextFields()


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


func initializeTextFields() 
    tfFirst.delegate = self // Error Here!
    tfFirst.keyboardType = UIKeyboardType.ASCIICapable
    
    tfSecond.delegate = self
    tfSecond.keyboardType = UIKeyboardType.NumberPad
    
    tfThird.delegate = self
    tfThird.keyboardType = UIKeyboardType.ASCIICapable
    
    tfFourth.delegate = self
    tfFourth.keyboardType = UIKeyboardType.NumberPad


func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool 
    var result = true
    let prospectiveText = (textField.text as NSString).stringByReplacingCharactersInRange(range , withString: string)
    
    if textField == tfFirst 
        if count(string) > 0 
            let disallowedCharacterSet = NSCharacterSet(charactersInString: "BW").invertedSet
            let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
        
            let resultingStringLengthIsLegal = count(prospectiveText) <= 1
        
            result = replacementStringIsLegal && resultingStringLengthIsLegal
        
    
    
    if textField == tfSecond 
        if count(string) > 0 
            let disallowedCharacterSet = NSCharacterSet(charactersInString: "0123456789").invertedSet
            let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
            
            let resultingStringLenthIsLegel = count(prospectiveText) <= 3
            
            result = replacementStringIsLegal && resultingStringLenthIsLegel
        
    
    
    if textField == tfThird 
        if count(string) > 0 
            let disallowedCharacterSet = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyz").invertedSet
            let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
            
            let resultingStringLenthIsLegel = count(prospectiveText) <= 1
            
            result = replacementStringIsLegal && resultingStringLenthIsLegel
        
    
    
    if textField == tfFourth 
        if count(string) > 0 
            let disallowedCharacterSet = NSCharacterSet(charactersInString: "0123456789").invertedSet
            let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
            
            let resultingStringLenthIsLegel = count(prospectiveText) <= 3
            
            result = replacementStringIsLegal && resultingStringLenthIsLegel
        
    
    return result

如您所见,我为我的文本字段添加了 IBOutlets,现在我想将此视图控制器添加为他们的委托。所以我可以检查文本字段中输入的内容。

我尝试了不同的方法。首先,我尝试将textfield.delegate = self 放入 viewDidLoad 方法中,但出现错误“致命错误:在展开可选值时意外发现 nil”,我认为这是因为未创建文本字段。接下来它尝试了 viewDidAppear 方法,结果相同。最后,在我将一个对象添加到 .xib 并将视图控制器类设置为其类以触发 awakeFromNib 方法后,我将textfield.delegate = self 放入该方法中。但是我在这里遇到了同样的错误。

有没有我没有想到的事情,或者我正在做一些不起作用的事情?

问候阿达卡斯

【问题讨论】:

不能在界面Builder中设置委托吗? 我试过了,但是当蓝线在我的视图控制器代码上时,我没有得到创建委托的提示。 首先,我无法重现您的问题。你的代码工作正常。其次,在 xib 文件中,选择“File's Owner”,然后在 Xcode 的右上角选择“显示身份检查器”,然后在类字段中输入您的 xib 的类名 好的,如果代码运行良好,那么问题可能来自我正在使用的 SimpleAlert 类。我已经按照你的描述设置了文件的所有者。 在 Interface Builder 中选择一个文本字段并按 Opt Cmd 6(连接检查器)。从 Outlets>delegate 拖动到 View Controller Scene 中的 View Controller Object。这行得通吗? 【参考方案1】:

由于您已经声明您的控制器符合UITextFieldDelegate 协议,请在 Interface Builder 中执行此操作:

    选择您的文本字段 显示连接检查器 会有一个Outlets 部分,下面有delegate。 将delegate右侧的圆圈拖到您的视图控制器对象上,如下所示

    对每个文本字段执行此操作

现在应该可以正确调用 textField 委托方法了。

【讨论】:

【参考方案2】:

didSet 呢?

class TestBaumViewController: UIViewController, UITextFieldDelegate 

    @IBOutlet weak var tfFirst: UITextField! 
        didSet 
            tfFirst.delegate = self
        
    
...

或者您也可以在 XIB 中拖动文本字段代表。 右键单击文本字段并将委托属性拖动到视图控制器。

【讨论】:

didSet 在初始化期间从不被调用:在委托发生之前在初始化程序中设置属性时不会调用 willSet 和 didSet 观察者。 这不是初始化。在这种情况下调用了didSet,你可以试试。 好吧,我不再遇到第一个错误了。但是,当我单击文本字段时,我在 AppDelegate.swift 文件中出现异常。 可以复制/粘贴崩溃日志吗? 尽快知道我将如何做;)。

以上是关于为 .xib 所有者的 ViewController 中的 textField 设置委托的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSSet/allTargets 获取 xib 所谓的“文件所有者”?

无法为自定义 UITableView 单元设置约束,在 xib 中创建,因为所有数据在大小类更改时消失

iOS异常:NSUnknownKeyException:“在将xib作为所有者连接到ViewController之后,”此类不符合键值的键值“

自定义 XIB 的“文件所有者”

使用 NSView 加载 Xib 文件

Swift将文本分配给xib文件中的标签