2016-09-30 5 views
4

表示警告ポップアップなどのUI関連の機能をいくつか持っています。画面の中央にアクティビティインジケータを表示したり、カスタムメッセージでUIViewにアニメーションを表示したりできます。
私は複数のviewController(この場合はVC1とVC2)で使いたいので、自分自身を繰り返すことはありません。
最初は、両方のVCで動作する次のコードを持っています。それらの機能を担うBaseVCから継承しています。
VC1はtablelViewが埋め込まれたUIViewController、VC2はcollectionViewが埋め込まれたUIViewControllerです。いくつかの理由によるところが ビューコントローラ間で共有されたUI機能

class VC1: BaseVC { 
    func viewDidAppear(animated: Bool) { 
     activityIndicatorBegin() 
    } 

    func btnPressed() { 
     activityIndicatorEnd() 
    } 
} 

class VC2: BaseVC { 
    func viewDidAppear(animated: Bool) { 
     activityIndicatorBegin() 
    } 

    func btnPressed() { 
     activityIndicatorEnd() 
    } 
} 

class BaseVC: UIViewController { 

    var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView() 
    var isCustomViewOnScreen = false 

    func activityIndicatorBegin() { 
     if activityIndicator.isAnimating() == false { 
      activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0,0,20,20)) 
      activityIndicator.center = view.center 
      activityIndicator.hidesWhenStopped = true 
      activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge 
      activityIndicator.color = UIColor.blackColor() 
      view.addSubview(activityIndicator) 
      activityIndicator.startAnimating() 
     } 
    } 

    func activityIndicatorEnd() { 
     if activityIndicator.isAnimating() == true { 
      activityIndicator.stopAnimating() 
      activityIndicator.removeFromSuperview() 
     } 
    } 

    func animateACustomViewOnScreen() { 
     if isCustomViewOnScreen == false { 
      // Some animation code 
     } 
    } 

    func removeCustomView() { 
     if isCustomViewOnScreen == true { 
      // Some removal code 
     } 
    } 
} 


は、私が代わりにUICollectionViewControllerからストレートのUITableViewControllerのためVC1とVC2を作ることにしました。
これは、UIViewControllerクラスであるこのBaseVCからはみ出すことができなくなることを意味します。

両方のVCがこれらの機能に到達できるようにするにはどうすればよいですか?

答えて

0

なぜUIActivityViewController自体をサブクラス化しないのですか? これはもっと論理的でクリーンです。

class VC1: UIViewController { 
    var customActivityIndicatorView: CustomActivityIndicatorView? = nil 

    func viewDidAppear(animated: Bool) { 
     if let view = view { 
      customActivityIndicatorView = CustomActivityIndicatorView(parentView: view) 
     } 
    } 

    func btnPressed() { 
     customActivityIndicatorView?.end() 
    } 
} 

class VC2: UITableViewController { 
    var customActivityIndicatorView: CustomActivityIndicatorView? = nil 

    func viewDidAppear(animated: Bool) { 
     if let view = view { 
      customActivityIndicatorView = CustomActivityIndicatorView(parentView: view) 
     } 
    } 

    func btnPressed() { 
     customActivityIndicatorView?.end() 
    } 
} 

class CustomActivityIndicatorView: UIActivityIndicatorView { 
    var isCustomViewOnScreen = false 

    convenience init?(parentView: UIView) { 
     if isAnimating == false { 
      self.init(frame: CGRect(x: 0, y: 0, width: 20, height: 20)) 
      center = parentView.center 
      hidesWhenStopped = true 
      activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge 
      color = UIColor.black 
      parentView.addSubview(self) 
      startAnimating() 
     } else { 
      return nil 
     } 
    } 

    func end() { 
     if isAnimating == true { 
      stopAnimating() 
      removeFromSuperview() 
     } 
    } 

    func animateACustomViewOnScreen() { 
     if isCustomViewOnScreen == false { 
      // Some animation code 
     } 
    } 

    func removeCustomView() { 
     if isCustomViewOnScreen == true { 
      // Some removal code 
     } 
    } 
} 
3

答えはProtocol Extensionsです。あなたは、プロトコルとしてBaseVCを定義し、それを実装するクラス全体で使用される共有ロジック追加することによって、これを拡張します。

(。BaseVCは、以下の例ではActivityIndicatorDisplayingと改称された)

protocol ActivityIndicatorDisplaying { 

    var activityIndicator: UIActivityIndicatorView { get set } 
    var showsCustomView: Bool { get } 

    func showActivityIndicator() 
    func dismissActivityIndicator() 
} 

extension ActivityIndicatorDisplaying where Self: UIViewController { 

    func showActivityIndicator() { 
    if activityIndicator.isAnimating() { return } 

    activityIndicator.center = CGPointMake(view.bounds.width/2, view.bounds.height/2) 
    activityIndicator.hidesWhenStopped = true 
    activityIndicator.activityIndicatorViewStyle = .WhiteLarge 
    activityIndicator.color = UIColor.blackColor() 
    view.addSubview(activityIndicator) 
    activityIndicator.startAnimating() 
    } 

    func dismissActivityIndicator() { 
    activityIndicator.stopAnimating() 
    activityIndicator.removeFromSuperview() 
    } 

    func animateACustomViewOnScreen() { 
    if !showsCustomView { 
     // Some animation code 
    } 
    } 

    func removeCustomView() { 
    if showsCustomView { 
     // Some removal code 
    } 
    } 
} 

class VC1: UITableViewController, ActivityIndicatorDisplaying { 

    var activityIndicator = UIActivityIndicatorView() 
    var showsCustomView: Bool = false 

    override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 

    showActivityIndicator() 
    } 

    func btnPressed() { 
    dismissActivityIndicator() 
    } 
} 

class VC2: UICollectionViewController, ActivityIndicatorDisplaying { 

    var activityIndicator = UIActivityIndicatorView() 
    var showsCustomView: Bool = true 

    ... 
} 
+0

良い答えを、しかし '拡張ActivityIndi​​catorDisplaying Self:UIViewController'' UIView'がまだ動作していることを表示していたら? –

+0

'.addSubview'はビューコントローラの' .view'プロパティで呼び出されるので、動作しません。 UIViewとUIViewControllerの両方で動作させたい場合は、 'Self:UIViewController'を削除してプロトコルの別のプロパティを定義する必要があります:' var view:UIView {get} ' – ozgur

+0

このソリューションの投票率がさらに高い理由ジェイソンの下の1つ?彼のやり方は、すべてのVCに余分なフラグを導入しません – user125972

関連する問題