2017-11-13 11 views
0

私はいくつかの移行プロトコルを書いています、と私は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としてTransitioningViewにキャストされたUIViewを考慮しません。

例:時々私は私がTransitioningViewであることが確認されているビューの周りに渡したいので

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

これは少し面倒です。より良いパターンがありますか?あなたの例では

+0

私は推測、あなたは次のようになります 'TransitioningView'プロトコルにいくつかのプロパティを追加することができます'var view:UIView {return self as UIView}' 'のように使用し、xvのように使用しますiew.backgroundColor、または単にmyController.viewにアクセスしてください – JuicyFruit

答えて

1

public protocol TransitioningView where Self: UIView、あなたはTransitioningViewUIViewからの継承が必要ですが、私はUIViewTransitioningViewのいずれかの実装を見ることができないことを定義しています。

これを行う方法について2つの例を挙げておきます。

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)?) { 

    } 
} 

TransitioningViewに準拠UIViewから継承するすべてのオブジェクトを作成します。この例では、これはあなたが利用どのくらいのオーバーキルに応じて、次のようになります。

まず、プロトコルのデフォルトの実装を作成することができますTransitioningView機能:最後の例は、カスタムクラスで直接TransitioningViewを実装します

extension UIView: 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 
    } 
} 

Extensions - The Swift Programming Language (Swift 4)

Protocols - The Swift Programming Language (Swift 4)

+0

これは、これらのトランジションを定義するためのパターンを変更するための興味深い考えですが、実際に*すべての*ビューがプロトコルに適合することは望ましくありません。私はちょうどいくつかのランダムなオブジェクトがそれに準拠していないことを確認したいです。 – GoldenJoe

+0

自分で定義した制約を使用することで、 'UIView'の子孫でないオブジェクトに対して' TransitioningView'プロトコルを使用できないようにします。あなたがすでにタイトルで質問に答えてくれて以来、あなたが何を求めているのか分かりません。 – Laffen

関連する問題