当协议扩展现有的Apple API协议时,不会调用协议扩展方法

问题描述:

我希望协议从继承来自Apple协议UIViewControllerTransitioningDelegate,添加其他协议要求并为该协议中的某些方法提供默认实现。当我这样做时,方法不会被调用。当我在类中实现方法时,方法被调用。当协议扩展现有的Apple API协议时,不会调用协议扩展方法

这里就是我说的:

class FirstViewController: UIViewController, SlideDismissor { 
    let transition: PercentDrivenInteractiveTransitionWithState? = PercentDrivenInteractiveTransitionWithState() 
} 

protocol SlideDismissor: UIViewControllerTransitioningDelegate { 
    var transition: PercentDrivenInteractiveTransitionWithState? { get } 
} 

extension SlideDismissor { 
    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return nil // I do return something here, but for this example it isn't necessary 
    } 

    func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 
     return transition 
    } 
} 

如果我添加以下代码的函数都被调用。

extension FirstViewController: UIViewControllerTransitioningDelegate { 

    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return nil // I do return something here, but for this example it isn't necessary 
    } 

    func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 
     return transition 
    } 

} 

这些方法我试图提供一个默认实现是可选的方法。

+0

我也尝试过为UIView提供默认实现ControllerTransitioningDelegate' – Mingming

我有同样的问题,试图做类似的事情。显然目前的协议扩展限制似乎是我们不能提供Objective-C协议的默认实现。因此,在UIKit中声明的任何协议都属于这个类别。这也是关于面向协议编程的以下建议article。 这是9月2016年 的有效我觉得你的痛苦=(但我想现在这种清洁剂推广方法不是暂时真的可行

对于这类问题更好的解决方案是可用的组合物,而不是继承。而不是符合SlideDismissor,委托给一个。

(我还没有测试此代码,甚至确信它编译,但是这是基本的方法,我想探讨。)

class FirstViewController: UIViewController { 

    // Rather than handle your own transitioning, delegate it to another, reusable, object.  
    override func viewDidLoad() { 
     // Your original protocol suggested that the view controller wanted 
     // to control what kind of transition was used, so we pass it as a paramater. 
     transitioningDelegate = SlideDismissor(transition: PercentDrivenInteractiveTransitionWithState()) 
    } 
} 

// In that object, implement all the delegate methods 
class SlideDismissor: NSObject, UIViewControllerTransitioningDelegate { 
    let transition: PercentDrivenInteractiveTransitionWithState? 

    init(transition: PercentDrivenInteractiveTransitionWithState?) { 
     self.transition = transition 
    } 

    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return nil // I do return something here, but for this example it isn't necessary 
    } 

    func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 
     return transition 
    } 
}