代码之家  ›  专栏  ›  技术社区  ›  Gagan_iOS

“textfieldDidbeginediting”与swift中协议“uitextfieldDelegate”的可选要求“textfieldDidbeginediting”几乎匹配

  •  1
  • Gagan_iOS  · 技术社区  · 6 年前

    我正在开发一个应用程序,我在其中为应用程序的每个功能创建了模块。我必须从一个模块UI控制器切换到另一个模块UI控制器。

    我在一个模块中有uicontroller,并将该控制器标记为 公众 访问标识符如下

    public class InterAccountTransferViewController: UIViewController {
       override public func viewDidLoad() {
        ......
        ......
       }
    }
    

    上述类还实现扩展中的UITextField委托。当我将上面的类创建为open access时,我会收到下面的textfield委托警告

    实例方法“textfieldDidbeginediting”几乎与可选方法匹配 协议的“textfielddidbginediting”要求 'UItextfieldDelegate'

    enter image description here

    现在没有调用TextField委托。当我试图通过将代表设为私有来关闭警告时,他们仍然没有被呼叫。

    请让我知道如何消除这些警告,并给代表们打电话。

    任何想法或建议都是很好的。我正在用Swift 4.2开发Xcode 10。如果我需要更多地解释我的问题,请告诉我。

    3 回复  |  直到 6 年前
        1
  •  3
  •   Michael SarpErdag    6 年前

    对于“几乎匹配”,编译器会告诉您两件事:

    1. 不匹配 :方法“textfieldDidbeginediting(:)与委托方法“textfieldDidbeginediting(:)不同。对于编译器来说,这本身不是问题,您只有一个具有某个名称的方法,它不知道名称,所以没关系。
    2. 非常像 委托方法“textfieldDidbeginediting(:)。所以编译器可以看到您可能打算将其作为委托方法,并且它告诉您,好吧,它不起作用。您所写的不是委托方法。

    编译器告诉您有问题,这很好。这不是很好,它不能解释问题的确切原因。

    问题是类的可见性比委托方法强。 你的班级是 public ,而委托方法只是 internal (因为 内部的 如果声明中没有访问说明符,则为默认值。)

    解决方法是给委托方法 公众的 访问说明符也是。

    你得换衣服

    func textFieldDidBeginEditing(_ textField: UITextField) {
        // ...
    }
    

    public func textFieldDidBeginEditing(_ textField: UITextField) {
        // ...
    }
    

    这将使编译器知道该方法实际上是一个委托方法。


    奖励内容…

    我是如何找到解决方案的? 我用xcode转载了这个问题。我点击了警告并阅读了修正本:“让‘textfielddidbeginediting’成为非公开的,使这个警告保持沉默。”我单击了“fix”,该行更改为“private func textfieldDidbeginediting(utextfield:uitextfield)”。所以我想也许可以改变它 公众的 而不是 private 会有更多帮助。我试过了,检查过了,结果成功了。

    为什么斯威夫特会这么做? 我不确定,但我的猜测是:如果一个类是公共的,但是协议方法是内部的,这意味着从模块的角度来看,单个视图控制器对象实现协议。但是,由于协议实现是内部的,所以从外部模块(例如从uikit)的角度来看,协议方法将不可用。但这在目标C运行时是不可能的,即使可能,也会很糟糕。悄悄地将协议方法公开或半公开是可能的,但不是很干净:例如,可以使textfieldDibegineding成为内部的,但当您将对象强制转换为uitextfieldDelegate伪对象时,您可以突然调用该方法,这也会令人惊讶。

        2
  •  2
  •   Sakshi    6 年前

    试试这个

    class InterAccountTransferViewController: UIViewController,UITextFieldDelegate {
     override func viewDidLoad() {
        super.viewDidLoad()
        //Attach delegates 
        self.textfield.delegate = self
     }
       //TextField Delegate Method
       public func textFieldDidBeginEditing(_ textField: UITextField) {
       }
    } 
    
        3
  •  1
  •   Robert Dresler Gustavo Vollbrecht    6 年前

    将您的方法也标记为 public

    public func textFieldDidBeginEditing(_ textField: UITextField)