1

概要:私は現在、カスタムアニメーションロジックを実装するカスタムUIViewサブクラスを持っており、ビュークラスがそのコードを配置するのに最適な場所であるかどうかはわかりません。カスタム、再利用可能なアニメーションコードはどこに行きますか?

UIViewサブクラスを使用するSwiftでiOSアプリケーションを作成していますが、DoorViewと呼んでいます。 DoorViewは、スワイプジェスチャーに応答してスライドアニメーションを実行して開くスライドドアを表します。

は、ここで私は今それを持っているように、完全なアニメーションです:私のビューコントローラの光を維持しようとして

enter image description here

、私は私のDoorViewクラスにこれらのアニメーションを扱う実際のコアアニメーションコードを置きます。 My View Controllerは、指定されたドアを開くために必要なジェスチャと一致するかどうかをチェックすることによってジェスチャを処理し、そうであれば、DoorViewでopen()メソッドを呼び出します。 ViewController中のSO

: 注:これはただのスライドアニメーションで、スライド型のチェックがで使用されます

@IBAction func swipe(sender: UISwipeGestureRecognizer) { 
     if (sender.direction.rawValue == currentDoorView.door.swipeDirection.rawValue) { 
      self.currentDoorView.open() 
     } 
    } 

そして、ここでは私のDoorViewクラスのopen()メソッドです他のタイプのドア(例えば、ヒンジ式ドア)と区別するための将来性。

func open(withDuration duration: CFTimeInterval = 1.0) { 

    /// We only slideOpen if switch statement below determines self.door is Sliding, 
    /// so we downcast as SlidingDoor so we can switch on door.slideDirection. 
    /// For each slideDirection case, a different translation is created, 
    /// which is then passed into the slideAnimation below. 
    func slideOpen() { 

     let slidingDoor = self.door as! SlidingDoor 
     let translation: CATransform3D 

     switch slidingDoor.slideDirection { 
     case .Down: 
      let height = baseLayer.bounds.height 
      translation = CATransform3DMakeTranslation(0, height, 0) 
     case .Left: 
      let width = openingLayer.bounds.size.width 
      translation = CATransform3DMakeTranslation(-width, 0, 0) 
     case .Right: 
      let width = openingLayer.bounds.size.width 
      translation = CATransform3DMakeTranslation(width, 0, 0) 
     case .Up: 
      let height = baseLayer.bounds.height 
      translation = CATransform3DMakeTranslation(0, -height, 0) 
     } 

     let slideAnimation = { 
      (completion:(() ->())?) in 
      CATransaction.begin() 
      CATransaction.setCompletionBlock(completion) 
      CATransaction.setAnimationDuration(duration) 
      self.openingLayer.transform = translation 
      CATransaction.commit() 
     } 

     /// Actual call to slideAnimation closure. 
     /// Upon completion, notify delegate and call walkThroughDoor() 
     slideAnimation({ 
      self.delegate?.doorDidOpen(self) 
      self.walkThroughDoor() 
     }) 
    } 

    /// Switch to determine door type, and thus appropriate opening animation. 
    switch self.door { 
    case is Sliding: 
     slideOpen() 
    default: 
     print("is not sliding") 
    } 
} 

アニメーションロジックをビュークラスに入れても問題ありませんか? a)これらのアニメーションは私のDoorViewに固有であり、b)animateWithDurationはUIViewのクラスメソッドなので、ビュー/ビュークラス自身でアニメーションを処理するための先例があるようです。

私は自分のアプリを開発し続けますが、私は独自のアニメーションでより多くのドアタイプを追加していきます。DoorViewがアニメーションコードで太ってしまう恐れがあります。その時点でDoorViewサブクラス(SlidingDoorView、HingedDoorViewなど)を作成するだけですか?

アニメーションを表示するには、View Controllerで処理する必要がありますか?私の問題は、VCの膨張に加えて、他のView ControllerでDoorViewを使用したい場合、コードを複製する必要があるということです。このように、私のDoorViewsは独自のアニメーションでパッケージ化されています。私のVCはopen()を呼び出すだけです。

+1

ニースのアニメーション。各アニメーションのようなサウンドは、独自のクラスでなければなりません。それをサブクラス化するのは、どのコードを再利用する必要があるかによって異なります。 – dbugger

+0

ああ、面白い!お返事をありがとうございます。その場合、アニメーションはどこから呼び出されますか? DoorViewクラスのアニメーションメソッド呼び出しをまだ処理しているのでしょうか、それともView Controllerで処理するのが理にかなっていますか? –

+1

Viewクラスでカプセル化することができれば、他のコントローラで使用する方が簡単になります。 – dbugger

答えて

1

私はあなたがそれを行うことができ、どちらも同じように受け入れられると思います。あなたはそれがドアの種類を知っているので、あなたのメインDoorViewクラスでドアタイプのための新しい列挙型に入れてドアビューコード

からアニメーションコードを区切るために拡張機能を使用して

1。

は次に、新しい迅速なファイルを作成し、DoorAnimation.swiftそれを呼び出すと、内側に置く:

extension DoorView { 
    func open(withDuration duration: CFTimeInterval = 1.0) { 
    switch doorType { 
     case .Hinged: 
     openHingedDoor(duration) 
     case .Sliding: 
     openSlidingDoor(duration) 
    } 
    } 

    func openSlidingDoor(withDuration duration: CFTimeInterval = 1.0) { 
    // Enter the custom code 
    // You can call use self to access the current door view instance 
    } 

    func openHingedDoor(withDuration duration: CFTimeInterval = 1.0) { 
    // Enter hinged door animation code 
    } 
} 

2.サブクラスDoorView

DoorView内の関数を作成します。

func open() { 
    print("WARNING: This requires an override.") 
} 

を次に、各サブクラス内でopen()をオーバーライドします。

どちらの構造にも長所と短所があります。私はドアがあまりにも多くのオプション1をしないかどうか言うだろう。彼らに多くの機能がある場合は、オプション2を実行する方が良いでしょう。

+0

お返事ありがとうございます!ですから、明確にするために、全体的なデザインパターン/ SoCを提案してください:ビューにはこの種のロジックを含めることは許容されますか?どちらの提案も、コード編成の面では優れていますが、どちらも引き続き独自のアニメーションを最終的に実装するビューを含んでいます。私はちょうどそれが正直であることを確認したい。 編集:これは、別のアニメーションクラスを提案した元の投稿の投稿者と矛盾しますか? –

+1

ビュークラス自体にアニメーションを入れることができます。たいていの場合、例外はありますが、ビューには独自のアニメーションタイプがあります。しかし、グループアニメーションのようなことをしている場合、[View]配列でフェードアウトするビューの束を得るのと同じように、ベースのViewクラスの拡張を使用し、静的なfuncFadeOut(ビュー:[View] ){}型の関数です。だから、ぼんやりした線がある。 –

関連する問題