2010-12-03 13 views
0

私はこのアプリケーションを持っています。このアプリケーションには、ユーザーが画面上で簡単な絵を描くことができるセクションが含まれています。私の考えは、2種類の絵を提供することです:粗いと滑らかな(ベジェ)ライン。iPhone - drawRectを見つけようとしています:

どのようにビルドされていますか:私はカスタムdrawRectメソッドを持つ透明なUIViewを持っています。私はdrawRectを完全に理解しているかどうかはわかりませんが、コードは部分的に動作しています。

動作方法:ユーザーが画面上で指を動かします。彼が最初に画面に触れると、TouchesBeganはmyPointsというmutable配列を作成し、最初の点の座標を保存してキャンバスをそのまま保存します(元に戻すことができます)。

その後、TouchesMovedルーチンはすべてのポイントを取得し、myPointsに追加します。この配列は、ユーザーがベジェ線を描くことを選択した場合に必要です。

「touchesEnded」が検出されたとき、アプリはユーザーが通常の線(ラフ)またはベジェをペイントしているかどうかを確認する必要があります。それがベジエでない場合、線は既に描画されています。ベジェが必要な場合は、キャンバスを消去し、TouchesBeganが保存したときと同じようにキャンバスを復元し、新しいベジェ近似を計算して(描画された点に合わせて最適なベジェ曲線になるようにリバースエンジニアリング)大まかなものを置き換える。

これらは私の問題です。

1)元に戻す方法は?私は最初にアンドゥを保存する新しいレイヤーを作成することを考えましたが、それを行うことでアプリのメモリ使用量が8から13Mbに増加しました...これが安全なレベルであればわかりません(このアプリケーションは3GS、iPod Touch 2nd G、Up、iPadを含む)次に、キャンバスを保存するためのキュー操作を開始することにしました。これは、空のイメージが保存される結果となっています(drawRect以外のコンテキストを取得できないため、保存メソッドがコンテキストに対してnilを取得しているとします)。

2)2番目の問題は最初の問題と似ています。この時点で、キャンバスを保存したときの状態にキャンバスを復元する必要がありますが、復元メソッドがdrawRectの外側にあるので、コンテキストにもそれがなくなります。

TouchesBegan、TouchesMovedおよびTouchesEndedおよびすべてのメソッドは、drawRectがあるのと同じクラスの中にあり、viewControllerではありません。

私の質問は:あなたはどうやってそれをやるのですか?

私は、マルチレベルの取り消しを提供する店舗で絵画アプリを見ました。私は彼らがどうしたのか想像することはできません。私の最初の試みでは、私が創造した層のために5メガバイトのメモリを消費していたので、そのような種類のアンドゥをすることは不可能です。私は絶望的です!

ありがとうございました

答えて

1

"キャンバス"を保存する理由は何ですか? (私はあなたが描いているイメージだろうと思っています)

私はあなたがしたいと思うのは、描画可能なオブジェクト(ラフな線、ベジェなど)をすべての点を持つオブジェクトに保存することです"パス"を作成し、次にあなたの描画可能オブジェクトすべてを含むコレクション(つまりnsmutablearray)を持っていれば、drawRectはそのコレクションを取り出して画面に描画します。

取り消しを実行したいときは、取り消しを実行したいときに、最後の描画可能オブジェクトをコレクションから削除するか、最後のポイントをコレクションに追加して再描画します。

drawRectの外で描画コンテキストを取得することはできませんが、データ構造(ポイント、描画可能オブジェクトなど)を更新し、[self setNeedsDisplay]を呼び出すことでコントロールを無効にしますOSコールをdrawRectと呼び、オブジェクトを画面に描画することができます。

EDIT:

私はコンセプトアプリの簡単な証明を作成した(C#のリサイズに...私は今でもMy Macへのアクセスを持っていますが、概念を理解するために十分に簡単ですしていない場合)、これを作品方法。サンプルコードは、あなたがより複雑な取得する場合、あなたが指の動きの速度に応じてラインのwithsと空想を取得する場合は、この概念は、例えば、いくつかの制限があることを

https://github.com/jaimedp/DrawEraseUndo

注意、です再描画はこれを処理しませんが、描画可能オブジェクトにさらに多くのプロパティを追加して、より多くの工夫をすることができます。

必要に応じてサンプルをiOSに移植します。

希望これは上の...私はuは上記の言ったことを取得しようとしています。..

+0

をUAのリンクを提供します(はい、キャンバスで私は画像を意味する)...これで問題が消しゴムです。ユーザーはオブジェクトの一部を指で消去することができます。ユーザーが行の一部(既に保存されている点)を消去すると、消去を再作成する必要があります。これは愚かではないでしょうか?最終的な画像が得られるまで、オブジェクトは完全にまたは部分的に繰り返し描画され、消去される。私はこれが最良の選択肢とは思わない。 – SpaceDog

+1

実際には、消去は、コレクション内の別の描画オブジェクトですが、背景色を使用しています(多分違うかもしれません)...あなたが何かを元に戻す(つまり、最後のエントリを取り除く)とき、コレクションからイメージを再作成する必要がありますopeationsはSimone可視画像 – Jaime

+0

に残っています上記のタイプミスについては申し訳ありません...私のIpadは私の上でトリックを演奏しています....私はコンセプトサンプル証拠へのリンクで答えを更新しました – Jaime

1

OK .holdに役立ちます...私は当初、私はそれをよく答えるだろうと思った...私はそのようなことを行っているので、前に..しかし、私は全体の質問と答えをハイメで読んで、それは私を多く混乱させました。しかし、とにかく私が解釈するものから..私は答えを与えることができます

私はタッチで保存された私の配列の助けを借りて図面を開始し、移動した...私はそれだけのように描画..私は瞬時に点の配列を空にして "setNeedsDisplay"アレイ内にポイントが見つからないため、すべてのポイントをクリアします。

大まかな描画の場合は、配列で描画しない場合は、そのことをお勧めします。

私も...そのユーザを決定することはラフや滑らかな曲線が最初に行われていない「touchesEnded」に..して、配列を使用してそれに応じて描画する必要があります望んでいる。..

Iを1つのより多くの事をお勧めしますuはラフな曲線を描画する方法を知っている希望と滑らかな曲線のために私は私の答えに

CGContext Draw Line slowly responding to fast finger movement

+0

の点で完全に解読しようとします。滑らかな曲線の描画は完璧です。それは私がこの質問にしなかった第三の問題を解決します。ユーザーが描画を終えた後、ベジェ曲線を計算するために回帰を行っていたため、ラフカーブを描くようにしました(アプリが速く反応するようにします)。そしてレンダリングとボイラの1秒間を行い、ラフカーブを平滑化したバージョンに置き換えました。カーブは本当にうまく滑らかですが、この解決策は最終的なレンダリングを取り除き、おそらく私はアプリからスムーズなライン機能を削除することもできます(私はラインが非常に粗いのでそこに配置しました)。ありがとう。 – SpaceDog

関連する問題