4

私は何週間も何かに取り組んできました (iOS) が、受け入れられる解決策を見つけられないようです。

要件

  • 10000x10000 ピクセルの背景画像を表示する
  • 応答性の高いズームとスクロール
  • カスタム描画されたオーバーレイ
  • オーバーレイの要素はインタラクティブで (要素をタップして強調表示するなど)、ピースをオンまたはオフにすることができます。
  • iOS4.0

これは架空の町の地図であり、その上に道路、線、エリア、建物が描かれたクレイジーなシステムと考えてください。さまざまな不透明度、いくつかのアイコン画像などで塗りつぶされた CGPath の混合物。これは、Google マップ アプリのより複雑なバージョンのようなものです。

私が試したこと:


1 - 複数の CATiled レイヤー

ビュー階層:

  • ScrollView
  • ->ContainerView
  • -->TiledView (CATiledLayer 10000x10000)
  • --->OverlayView (CATiledLayer 10000x10000)

結果: 左右の魔法のリンゴ キャッシュからタイルをドロップします。2 つの CAtiledlayers は正しいパスではないようです。オーバーレイの更新は高速ではありません。


2 - OverlayView の TiledView のサブクラス

ビュー階層:

  • ScrollView
  • ->OverlayView (TiledView CATiledLayer 10000x10000 のサブクラス)

結果: オーバーレイの更新をレンダリングするのに時間がかかりすぎます。タイルの更新が遅い


3 - 単一のコンテナ ビューを使用した Scrollview

ビュー階層:

  • ScrollView
  • ->ContainerView (10000x10000)
  • -->OverlayView (CALayer 10000x10000)
  • -->TiledView (CATiledLayer 10000x10000)

結果: OverlayView が大量のメモリを消費するため、機能しません。TileView は CATiledLayer によってサポートされているため問題ありません


4 - スクロール デリゲートと CTM スケール/変換を使用して大きいことをシミュレートする OverlayView

ビュー階層:

  • OverlayView (CALayer 1024x768)
  • ScrollView
  • ->TiledView (CATiledLayer 10000x10000)

結果: scrollview デリゲートを使用して、オーバーレイ ビューのオフセットとズームを調整します。この方法の問題点は、drawrect が 1 秒間に 100 回呼び出されることと、オーバーレイ ビューの描画速度が十分ではないため、完全に 1 fps まで遅れることです。


それが私がいるところです。この最後の方法は何かに取り組んでいるように感じますが、ドローレクトの狂気を飼いならすにはクレイジーな作業が必要になるでしょう. 他の考えは、OpenGL で何かに取り組もうとすることです。

それらを実行する前に、コミュニティに、同様の要件に直面して彼らが何をするか/何をしたかを確認するように頼むと思っていました。

助けてくれてありがとう。

4

3 に答える 3

2

私の提案は、スクロールビューに2つのビューを含めることです。背景のCATiledLayerビュー。2番目のビューは、背景ビューの上にあるカスタムUIViewです。ここで、カスタム描画を行います。カスタムビューには、今のところ何もしないdrawRect:メソッドが必要です。

したがって、customViewに何も入れずにこれを試して、スクロールなどが希望どおりであることを確認してください。問題がバックグラウンドビューにあり、それを解決する必要がある場合。

その時点で、カスタムビューは描画を開始します。drawRectで更新するrectを取得することに注意してください。おそらく、キャンバス全体に描画する必要のあるアイテムが1,000個あるので、それぞれにframeプロパティがあるので、現在のズームとフレームで何を描画する必要があるかを判断できます。あなたはそれらのアイテムを描くだけです。

この一般的な手法は、過去に私にとってうまく機能しました。

EDIT2:

そのため、デバイスで実行しているときに、「割り当てできません」というメッセージを複製しました。したがって、プランBです。実行できるのは、スクロールビューと新しいUIViewサブクラスの2つのビューを持つコンテナビューを作成することです。scrollViewには巨大なモンスタービューがあります。サブクラスビューには、まさにUIScrollViewフレームであるフレームがあります。

次に、scrollViewメッセージ「scrollViewDidScroll:」などが表示されることを確認します。

scrollViewが安定している場合、または上記のメッセージを入力すると、カスタムUIViewサブクラスは、drawというメ​​ッセージを取得しますが、scrollViewcontentOffsetであるオフセットを使用します。

カスタムクラスが実行する必要のある作業は同じです。drawRect原点を使用する代わりに、その点を取得し、scrollViewのcontentOffsetによってオフセットします。これで、描画するときに、drawRect:rectオフセットでスクロールビューオフセットによって正に渡されたポイントのスコープ内にあるオブジェクトを探しています。

于 2012-08-27T23:24:21.363 に答える
1

パス ベースのマップを 1 回描画しましたが、背景イメージがなく、パスのみでした。drawrect (Scrollview なし) でビューを 1 つだけ使用し、自分でスクロール/ズームを実装しました。特に高解像度の ipad3 では、フル解像度のイメージコンテキストの割り当てに問題があるため、いくつかのパフォーマンスの問題があります。

  • パスに影などを使用しないでください。パフォーマンスが低下します。
  • パス/オブジェクトのすべての境界ボックスを事前に計算し、それらをある順序で保存して、可視パス/オブジェクトをできるだけ速く検索できるようにします。
  • ズームレベルごとに異なる詳細なパスセットを使用します。

しかし、最後にはopenGLがより良い解決策だと思います。

于 2012-08-28T06:27:16.890 に答える