我正在编写一些转换协议,我希望它们仅适用于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)?)
}
但这似乎并不合适。编译器不会将已转换为TransitioningView的UIView视为UIView。
示例:
let x = myController.view as? TransitioningView
x.animateTransition(popTo: nil, finished: nil) // OK
x.backgroundColor = .clear // NOPE
这有点烦人,因为有时我想传递一个我已经确认为TransitioningView的视图。有更好的模式吗?
答案 0 :(得分:1)
在您的示例public protocol TransitioningView where Self: UIView
中,您定义TransitioningView
需要UIView
的继承,但我无法看到TransitioningView
的任何实现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
中使用相同的默认实现。这种行为可以被覆盖"在扩展或类本身。
extension TransitioningView where Self: UITextField {
public func animateTransition(pushFrom: UIView?, finished: ((Bool) -> Void)?) {
// Some custom transition
}
}
或
class MyCustomView: UIView, TransitioningView {
func transitionDuration(popTo: UIView?) -> TimeInterval {
return 2
}
}
供进一步参考: