'textFieldDidBeginEditing'与Swift中协议'UITextFieldDelegate'的可选要求'textFieldDidBeginEditing'几乎匹配

时间:2019-01-07 11:37:33

标签: ios swift

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

我在模块中有UIController,并将该控制器标记为 Public 访问标识符,如下所示:

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

上述类还实现了扩展中的UITextField委托。当我将上述类创建为开放访问时,我在TextField委托上收到警告,如下所示

  

实例方法'textFieldDidBeginEditing'与可选方法几乎匹配   协议的要求'textFieldDidBeginEditing'   'UITextFieldDelegate'

enter image description here

现在不调用文本字段委托。当我试图通过将代表设置为私人身份来关闭警告时,仍然没有调用它们。

请让我知道如何使这些警告静音并同时致电代表。

任何想法或建议都会很棒。我正在使用Swift 4.2开发Xcode 10。请让我知道是否需要进一步解释我的问题。

4 个答案:

答案 0 :(得分:4)

With "Nearly matches", the compiler tells you two things:

  1. It doesn't match: the method 'textFieldDidBeginEditing(_:)' is not the same as the delegate method 'textFieldDidBeginEditing(_:)'. This is in itself not a problem for the compiler, you just have a method with some name, and it doesn't know the name, so it's okay.
  2. It very much looks like the delegate method 'textFieldDidBeginEditing(_:)'. So the compiler can see that you probably intended this to be a delegate method, and it is telling you that, well, it did not work. What you have written is not a delegate method.

It's nice from the compiler that it tells you that there is a problem. It's not so nice that it doesn't explain what the problem is exactly.

The problem is that your class has more visibility than the delegate method. Your class is public, while your delegate method is just internal (because internal is the default, if you don't have an access specifier in your declaration.)

The fix is to give the delegate method a public access specifier too.

You have to change

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

to

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

This will let the compiler know that the method is indeed intended to be a delegate method.


Bonus Content...

How did I find the solution? I reproduced the issue in Xcode. I clicked on the warning and read the Fixup: "Make 'textFieldDidBeginEditing' non-public to silence this warning". I clicked "Fix" and the line was changed to "private func textFieldDidBeginEditing(_ textField: UITextField)". So I figured that maybe turning it public instead of private would help even more. I tried it, checked it, and it worked.

Why does Swift even do this? I'm not sure, but my guess is this: if a class is public, but the protocol method is internal, it would mean that an individual view controller object implements the protocol when you look from the perspective of the module. But since the protocol implementation is internal, the protocol method would be unavailable when looking from the perspective of outside modules, e.g. from UIKit. But this is not possible in the Objective C runtime, and even if it were possible, it would be bad. Silently making the protocol methods public or semi-public would be possible, but not very clean: e.g. one could make textFieldDidBeginEditing internal, but when you cast the object to a UITextFieldDelegate pseudo-object, you can suddenly call that method, which would also be surprising.

答案 1 :(得分:2)

尝试一下

class InterAccountTransferViewController: UIViewController,UITextFieldDelegate {
 override func viewDidLoad() {
    super.viewDidLoad()
    //Attach delegates 
    self.textfield.delegate = self
 }
   //TextField Delegate Method
   public func textFieldDidBeginEditing(_ textField: UITextField) {
   }
} 

答案 2 :(得分:1)

还将您的方法标记为public

public func textFieldDidBeginEditing(_ textField: UITextField)

答案 3 :(得分:0)

只需在您的函数中添加 public 访问修饰符即可。

public func textFieldDidBeginEditing(_ textField: UITextField) {
     // do whatever you want
}
相关问题