0

すべてのクラスが他のすべてのクラスを知っているようにクラスを編成するのはよくないとよく耳にします。そのため、他のクラスのプロパティとして存在するクラスには、親について知らないようにしています。しかし、UIView では実現できません。

問題はUIViewsだけでなく発生するため、質問はより一般的な背景から来ています。4 つのインスタンス変数として 4 つの車輪を持つオブジェクトとして車があり、左前輪が破裂した場合。左後輪がメッセージを受け取るはずです。良い方法でシステムを設計するにはどうすればよいですか?

Objective-C の UIView の例: 画面全体にカスタム UIView を使用しています。すべてのレイアウトを管理します。2 つのサブビューだけでシンプルに保たれているとしましょう。

@interface BackgroundView : UIControllerView {

    CustomViewA *buttonA;
    CustomViewB *buttonB;
}
@end

@interface CustomViewA : UIButton

@interface CustomViewB : UIButton

誰かがボタン A を押すと、ボタン B が何かをする必要があります (例: 赤に変わります)。私が見るいくつかのオプションがあります:

  1. ボタン A のデリゲートをボタン B に設定すると、A のすべてのイベントが B の実装ファイルに送られます。すべてのイベントがボタン B と関係があるとは限りません。
  2. BackgroundView のシングルトンを作成し、ボタン A にボタン B のプロパティを取得させるか、ボタン B への呼び出しを転送する BackgroundView のメソッドを呼び出します。複数の Background が必要な場合は、2 つの BackgroundView を持つさらに上位のクラスを作成できます。 (いい音ではありません)。
  3. UIViews に実装された親を呼び出してから、2 のようにメソッドを呼び出すか、直接変更します。UIView を使用しない場合の問題は、機能を他の「親」クラスにコピーしますか?

このような問題を解決するより良い方法はありますか? または、1 つの方法を大幅に最適化できますか?

4

2 に答える 2

2

おそらく、そのすべてのロジックは、自分が制御するビューについてすべてを知っている ViewController に属していますが、ビューはビュー コントローラーや互いについて何も知りません。

ビューは、委譲 (またはターゲット アクション) を介してビュー コントローラーと通信する必要があり、ビュー コントローラーが決定を下し、メッセージを他のビューに転送する必要があります。

ところで、iTunes University の Stanford コースを見てみましょう。MVC (Model View Controller) について話すのは 1 回目か 2 回目のクラスだと思います。とても役に立ちます: https://itunes.apple.com/us/course/coding-together-developing/id593208016

于 2013-02-24T13:25:28.137 に答える
2

@Odrakir はここで Model-View-Controller について言及していますが、その通りです。これが最初の目的地です。それが役立つ場合は、そのパターンを例に適用する方法を次に示します。

プロパティを持つモデル クラスがありますcolor。ドキュメントベースのアプリケーションでは、通常、ドキュメントモデルです。非ドキュメント ベースのアプリケーションでは、モデルをアプリケーション デリゲート インスタンスから切り離すのが一般的です。簡単にするために、後者のケースにいるとしましょう。次のクラスがある場合があります。

// "Model"
@interface MyModel : NSObject
@property (nonatomic, readwrite, copy) UIColor* color;
@end

// AppDelegate
@interface MyAppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, readonly, retain) MyModel* model;
@end

// "View"
@interface CustomViewA : UIButton
@end

@interface CustomViewB : UIButton
@end

// "Controller"
@interface MyViewController : UIViewController

@property (nonatomic, readwrite, assign) IBOutlet UIView* buttonA;
@property (nonatomic, readwrite, assign) IBOutlet UIView* buttonB;

- (IBAction)doActionA: (id)sender;
- (IBAction)doActionB: (id)sender;

@end

基本的なパターンは次のとおりです。ビューからのアクションは、コントローラーによるモデル変更アクションをトリガーします (ターゲット/アクション パターン)。これを実現するには、ボタン A のアクションを-doActionA:コントローラー (IB の「ファイルの所有者」) および (B についても同様) に接続することで、それらを接続します。次に、コントローラーのアクション メソッドがトリガーされると、モデルを変更し、モデルの変更の結果として再描画が必要なビューを無効にする必要があります。ビューをコントローラーの IBOutlets にプラグインし、コントローラーで[self.buttonA setNeedsDisplay]. 次に、ビューが描画するときに、正しく描画するために必要な状態をモデルから読み取る必要があります。

MacOS では、バインディングを使用してビューをモデルにリンクすることで、手動による無効化の手順を省略できることに注意してください。その場合、モデルを変更すると、ビューが自動的に無効になります。iOS/UIKit にはバインディングがないため、この無効化は手動で行う必要があります。

于 2013-02-24T15:03:21.980 に答える