Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 我可以将协议限制为一种类型的类吗?_Swift_Uiview_Protocols - Fatal编程技术网

Swift 我可以将协议限制为一种类型的类吗?

Swift 我可以将协议限制为一种类型的类吗?,swift,uiview,protocols,Swift,Uiview,Protocols,我正在编写一些转换协议,我希望它们只对UIView类可用: public protocol TransitioningView where Self: UIView { func transitionDelay(pushFrom: UIView?) -> TimeInterval? func transitionDuration(popTo: UIView?) -> TimeInterval func transitionDuration(pushFrom:

我正在编写一些转换协议,我希望它们只对UIView类可用:

public protocol TransitioningView where Self: UIView
{
    func transitionDelay(pushFrom: UIView?) -> TimeInterval?
    func transitionDuration(popTo: UIView?) -> TimeInterval
    func transitionDuration(pushFrom: UIView?) -> TimeInterval
    func animateTransition(popTo: UIView?   , finished: ((Bool) -> Void)?)
    func animateTransition(pushFrom: UIView?, finished: ((Bool) -> Void)?)
}
但这似乎并不完全正确。编译器不考虑将UIVIEW转换为UIVIEW的UIVIEW。

例如:

let x = myController.view as? TransitioningView
x.animateTransition(popTo: nil, finished: nil) // OK
x.backgroundColor = .clear // NOPE

这有点烦人,因为有时我想传递一个我已经确认为TransitioningView的视图。有更好的模式吗?

在您的示例中,
公共协议转换视图,其中Self:UIView
,您定义了
转换视图
需要从
UIView
继承,但我看不到
转换视图
UIView
的任何实现

我将举两个例子说明如何做到这一点

首先,您可以创建协议的默认实现:

extension TransitioningView {

    public func transitionDelay(pushFrom: UIView?) -> TimeInterval? {
        return 1
    }

    public func transitionDuration(popTo: UIView?) -> TimeInterval {
        return 1
    }

    public func transitionDuration(pushFrom: UIView?) -> TimeInterval {
        return 1
    }

    public func animateTransition(popTo: UIView?, finished: ((Bool) -> Void)?) {

    }

    public func animateTransition(pushFrom: UIView?, finished: ((Bool) -> Void)?) {

    }
}
此示例将使从
UIView
继承的每个对象符合
TransitioningView
,这可能是一个过度杀伤力,具体取决于您使用
TransitioningView
功能的程度:

extension UIView: TransitioningView {}
最后一个示例将直接在自定义类中实现
TransitioningView

class MyCustomView: UIView, TransitioningView {}
class MyCustomLabel: UILabel, TransitioningView {}
无论您如何实现,它们都在
扩展转换视图中使用相同的默认实现。此行为可以在扩展或类本身中“重写”

extension TransitioningView where Self: UITextField {

    public func animateTransition(pushFrom: UIView?, finished: ((Bool) -> Void)?) {
        // Some custom transition
    }
}

供进一步参考:


我想,您可以向
TransitioningView
协议添加一些属性,就像
var-view:UIView{return self-as-UIView}
,然后像x.view.backgroundColor一样使用它,或者只访问
myController.view
这是一个有趣的想法,可以更改定义这些转换的模式,但我并不希望每个视图都符合协议。我只是想确保某些随机对象不能符合它。通过使用您自己定义的约束,您可以确保
transitionview
协议不能用于非
UIView
后代的对象。我不确定我是否理解你的问题,因为你已经得到了标题中问题的答案。
class MyCustomView: UIView, TransitioningView {

    func transitionDuration(popTo: UIView?) -> TimeInterval {
        return 2
    }
}