【问题标题】:Issue with passing UIViewcontroller carrying delegate as parameter to swift function将带有委托的 UIViewcontroller 作为参数传递给 swift 函数的问题
【发布时间】:2015-01-09 11:53:41
【问题描述】:
class func invite(_cntrl : UIViewController) 
{
  // code to open mail composer sheet
}

此方法需要接受符合MFMailComposeViewControllerDelegate的控制器。

目前它给出了错误

Type 'UIViewController' does not conform to protocol 
'MFMailComposeViewControllerDelegate'

如何通过uiviewconroller符合MFMailComposeViewControllerDelegate

类似:

class func invite(_cntrl : UIViewController<MFMailComposeViewControllerDelegate>)
{
   // code to open mail composer sheet
}

【问题讨论】:

标签: ios iphone swift ios8


【解决方案1】:

我相信如果您将参数类型设置为 MFMailComposeViewControllerDelegate 它会接受。

所以你的功能是:

class func invite(_cntrl : MFMailComposeViewControllerDelegate)

Swift Language Guide 中作为类型的协议中找到

编辑:

进一步澄清后,由于您希望能够通过也符合 MFMailComposeViewControllerDelegate 的 UIViewController 的子类,因此扩展 UIViewController 类似乎是最好的方法。 (这些类似于 ObjC 类别。

例如

extension UIViewController : MFMailComposeViewControllerDelegate
{
  optional func mailComposeController(_ controller: MFMailComposeViewController!,
            didFinishWithResult result: MFMailComposeResult,
                          error error: NSError!)
  {
     self.dismissViewControllerAnimated(flag:true, completion:nil); 
  }
}

【讨论】:

  • 如果我这样做,我将无法写 _cntrl.presentViewController(mailComposer!, animated: true, completion: nil) 来展示表单
  • 将其转换为 UIViewController 或也实现了 Delegate 的 UIViewController 的子类?
  • 不能转换为控制器的特定子类,因为多个子类可能会调用此方法。也不能转换为 UIViewController,给出另一个明显的错误。
  • 对不起,我的大脑终于决定工作了。似乎有两种处理方法。您可以扩展 UIViewController 类以符合我建议的 MFMailComposeViewControllerDelegate 。或使用泛型,但似乎没有明显的方法可以使用作为子类并符合协议的泛型,在这种情况下,您需要将其作为 UIViewController 的子类并符合 MFMailComposeViewControllerDelegate
【解决方案2】:

我不知道确切的解决方案。但是,如果您想检查对象是否符合该特定协议,则作为替代方法,使用 is 关键字(也可以使用 as) 在这种情况下,它看起来像:

class func invite(_cntrl : UIViewController)
{
    if _cntrl is MFMailComposeViewControllerDelegate
    {
        println("Confirms to protocol")
    }
    else
    {
        println("Not confirm")
    }
}

Checking for Protocol Conformance中提到了这种方法

您可以使用类型转换中描述的isas 运算符来检查 用于协议一致性,并强制转换为特定协议。检查 for 和强制转换为协议的语法与 检查并转换为类型:

如果实例符合协议,is 运算符将返回 true,如果不符合,则返回 false

向下转换运算符的as? 版本返回协议类型的可选值,如果实例不符合该协议,则此值为nil

向下转换运算符的 as 版本强制向下转换为协议类型,如果向下转换不成功,则会触发运行时错误。

【讨论】:

    【解决方案3】:

    在 Swift 3 中你可以做到这一点

    class func invite(_cntrl : MFMailComposeViewControllerDelegate) 
    {
       // code to open mail composer sheet
       // You can cast it to a UIViewController subclass if you need it
    }
    

    【讨论】:

      【解决方案4】:

      你可以这样做,

      func setDelegate<T : UIViewController>(controller: T) where T: YourDelegateName{
          delegate = controller
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多