0

Core Graphicsとジェスチャレコグナイザー(OpenGLやタッチイベントではない)を使用するiphone/ipadで最初のアプリを実行しています。アプリ、ビュー、コントローラーはIBを使用してセットアップされました。これは、ViewController内の単なるビューです。CGコンテキストに描画するためのCG呼び出しを追加しました。ジェスチャはビューに追加されますが、ビューコントローラで処理されます。ビューコントローラは、アクセサを使用して、ビューに描画されるものを決定する変数を変更します。計算(つまりモデル)はビューに埋め込まれています。このアプリは非常にうまく機能しますが、メールで送信したり、描画したものを保存したりするなどの機能を追加したいと思います。(私は他のグラフィックスコンテキストが必要になることを知っています)。

従来の知識では、MVCパラダイムを使用する必要があると言われています。これは、モデルをビューからそれ自体のオブジェクトに分解することを意味します。そこで、コードをリファクタリングしました。モデルのNSObjectを手動で追加しました。これには、データと必要なメソッドが適切に含まれています。コンパイルエラーや警告はありません。

ここで、ビューのdrawRectがトリガーされたときに、コントローラーを介してモデルから更新された画像を取得したいと思います。画像が返されると予想される重要な場所で、NULLが返されます。オブジェクト参照が正しくない可能性がありますが、混乱して霧を切り抜けることができず、真空で作業しているので、あなたの助けを求めています。読んでくれてありがとう。

まとめと質問

View Controllerには、モデルに渡すことができる現在のパラメーターが常にあります。モデルは、これらのパラメーターを指定してビットマップ画像を計算できます。私はそれだけのダウンがあるとかなり確信しています。

私の質問は(さまざまな言い方をすれば):

モデルからビューに画像を取得するための最良の方法は何ですか(コントローラーを介して:^)ビューは、要求を開始するためにビューコントローラーにメッセージをどのように送信する必要がありますか?

モデルはどのようにして画像をコントローラーに返すことができますか?CGContextRefを、推奨するチェーンに戻すだけだと思います。

私について:私はOOP、Objective-C、Xcode、およびIBを初めて使用します。私はスタンフォード大学の講義のほとんどを数回見、ゴールドスタインのダミーの本を研究し、アップルのドキュメントを精査しました。初心者がこれらの情報源から適切なレベルの回答を収集することは困難です。もっと「経験」が必要です。私はとても環境に配慮しているので、ビューのインターフェイス定義に「myViewController * viewController」を含める以外に、ビューコントローラーを参照する方法すらわかりません。私はここStackoverflowで同様の質問に対する答えをグーグルで読んでいます。私は何も適切なものを見つけられなかったと信じることができません。私は、実用的な原則が私のガイドとして役立つことを望んでいます。

お知らせ下さい。

これは、十分に回答されなかった、view-instance-drawrectのモデルデータへの参照に似ています。

4

4 に答える 4

0

必要に応じて試すことができる 1 つのことは、NSNotifications を使用することです。

ビューはジェスチャ情報を取得し、(ダイレクト メッセージングを介して) 高レベルのイベントをコントローラーに送信します。コントローラーは、これらの高レベルのイベントを受け取り、モデルに変更を加えます。モデルはこれらの変更を消費し、変更を懸念する人に NSNotifications を送信します。

ビューはデータを表示する方法であるため、モデルについて既に認識しているため、ビューはこれらの変更をすぐにサブスクライブできます。モデルはビューについて実際には認識していないため、メッセージを直接送信する必要があります。ただし、どこかでモデルの変更に関心があるため、NSNotifications を使用してその情報をブロードキャストおよび公開します。このように、特に複雑なモデルやより単純なビューでは、ビューは関心のあるものだけにサブスクライブします。一度に NSNotifications をリッスンする複数のビュー (または何でも) を簡単に持つこともできます。

もう 1 つのオプションは、iPhone がサポートする Key Value Coding/Observing ですが、Mac 上の Cocoa ほど根深いものではありません。これにより、通知の多くが半自動的に処理されるため、それも考慮する必要があります。

于 2011-01-23T23:22:17.237 に答える
0

まず、パラメータによってデータが変更されるたびに再描画する必要があります。したがって、ビューを再描画する必要があるときに新しいデータを要求する代わりに、ビューまたはビュー コントローラーにデータを監視させて、データが変更された場合にビューが再描画されるようにします。drawRect は、特にビュー コントローラーから間接的にではなく、データを要求するべきではありません。これは、ビューがそのビュー コントローラーについて知る必要があるため (データを要求できるようにするため)、MVC 設計全体を壊します。次に、速度を上げるために、cgcontext を使用して画像を直接描画しますCGContextDrawImage(GContextRef c, CGRect rect, CGImageRef image);

于 2011-01-25T12:47:56.130 に答える
0

モデルの画像が変更されたときにビューが新しい画像を取得する必要があることを正しく理解している場合。ウィルが言ったように、通知またはキー値の監視を使用できます。モデルはビューについて知る必要がなく、ビューはモデルへの強い参照を持つべきではないためです。これを行うには、View Controller の viewDidLoad メソッドにこれを追加します。

[model addObserver:self.view forKeyPath:@"<replace this with the name of the image property in the model>" options:NSKeyValueChangeNewKey context:NULL];

次に、uiview サブクラスでこのメソッドを作成します。

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqual:@"<replace this with the name of the image property in the model>"] {
         // set an image property that has been added to the uiview
         // the image property should be a weak reference ie. (nonatomic, assign)
         self.image = [change valueForKey:NSKeyValueChangeNewKey];
         [self setNeedsDisplay];
    }
}

最後に、 drawRect: メソッドで画像を描画する必要があります。

于 2011-01-24T00:01:59.160 に答える
0

ビュー間のリンケージをセットアップする方法 | コントローラー | モデル:

view|controller - ビュー コントローラーの loadView メソッドから、「self」への参照を含むメッセージ「hello:」をビューに送信しました。(ビュー オブジェクトの) hello メソッドで、ビュー コントローラーへのポインターをグローバル変数に格納して、後で使用できるようにしました。

controller|model - ビュー コントローラーにモデル オブジェクトのインスタンスを割り当て/初期化し、そのポインターをビュー コントローラーのグローバル変数に保存しました。

これら 2 つのポインターをビューからモデルへの橋渡しとして使用することができました。IBとのこの連携を達成できたかどうかを知るのに十分なほど、自分が何をしているのかわかりません。

仕組みの要約

drawRect は、更新された画像のリクエスト/メッセージをビューコントローラーに送信します。

ビュー コントローラーは好きなように動作できますが、ジェスチャ ハンドラーによって調整されたパラメーターを持っているため、それらのパラメーターを使用して特定の要求をモデルに渡すことができます。

次に、モデルは CG でビジー状態になり、(モデルのビットマップ コンテキストから) CGBitmapContextCreateImage を使用し、CGImageRef を (View Controller に) 返します。次に、View Controller は元のリクエストの結果と同じ CGImageRef を返します。次に drawRect は [[UIImage imageWithCGImage:modelImage] drawInRect:rect] を実行して画像をビューに配置します。

考えられるマイナス面、最終的な考え

遅くなるかもしれませんが、それはただのパラノイアかもしれません。モデルは通常、ビットマップ イメージを作成するために 8K 以上の線を描画しますが、ビューは結果のピクセルをコピーするためにそれほど多くの作業を行う必要はありません。インストゥルメントを使用して、何が起きているかを確認する必要があります。

また、画質も気になります。大丈夫そうです。最初にCGbitmapコンテキストに描画し、次にCGBitmapContextCreateImageを通過し、最後に上記のようにUIImage imageWithCGImageを通過しても、何も失うとは思いません。すべて同じ正確なサイズ。

于 2011-01-25T07:32:15.503 に答える