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



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

这就是我要说的:

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
    }
}

我尝试为其提供默认实现的这些方法是可选方法。

对于这类问题,更好的解决方案是使用组合而不是继承。与其服从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
    }
}

我在尝试做类似的事情时遇到了同样的问题。显然,协议扩展的当前限制似乎是我们无法提供Objective-C协议的默认实现。因此,在UIKit中声明的任何协议都属于此类别。下面关于面向协议编程的推荐文章也说明了这一点。有效期自 2016 年 9 月起生效。我感觉到你的痛苦=(但我想目前这种更干净的扩展方法暂时并不可行

最新更新