2011-12-14 17 views
2

私は本当に助けが必要です! 私は200x200の小さな50pxタイルのようなタイルのロードを含むマップを構築しています。これらのタイルはUIScrollViewに配置されているので、マップ上で自分自身をドラッグすることができます!本当にうまくいくの?マップにはあまりにも多くのサブビューがあるので、それは非常に遅いです。ios機能をスピードアップ

右のように、スクロールするとサブビューが読み込まれます。問題は、あまりにも時間がかかり、スクロールが少し遅くなる/遅くなることです。この機能を改善してもらえますか?私はアイデアがありません。グランドセントラルディスパッチを発見しましたが、私はそれをどのように使用するか迷いません。

は、ここに私のコード

-(void)loadMapTiles { 
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_apply(1, queue, 
       ^(size_t row) { 
        int radiusX = 11; 
        int radiusY = 7; 
        int y = currentCoord.y-radiusY; 
        for(int x = currentCoord.x-radiusX; x < currentCoord.x+radiusX+1; x++) { 
         int currTag = mapSize.width*(y-1)+x; 
         if(![mapScroller viewWithTag:currTag]) { 
          UIImageView *mapTile = [[UIImageView alloc] initWithFrame:CGRectMake(50*x, 50*y, 50, 50)]; 
          int mapNo = (rand() % 20) + 1; 
          if(mapNo > 11) { 
           mapNo = 1; 
          } 

          mapTile.image = [UIImage imageNamed:[NSString stringWithFormat:@"desert_map%d_50.gif", mapNo]]; 

          //Tag the mapTile so that we can find it again! 
          [mapTile setTag:currTag]; 

          [mapContentView addSubview:mapTile]; 
          [mapTile release]; 
         } 
         if(x == currentCoord.x+radiusX && y < currentCoord.y+radiusY) { 
          x = currentCoord.x-radiusX-1; 
          y++; 
         } 
        } 
        //Remove the other tiles outside the radius! 
        for (UIView *mapTile in [mapContentView subviews]) { 
         if(mapTile.frame.origin.x/50 < currentCoord.x-radiusX || mapTile.frame.origin.x/50 > currentCoord.x+radiusX || mapTile.frame.origin.y/50 < currentCoord.y-radiusY || mapTile.frame.origin.y/50 > currentCoord.y+radiusY) { 
          [mapTile removeFromSuperview]; 
         } 
        } 
       }); 
} 

上記のマップ構築の機能を呼び出す関数です:私はOBJ-Cの開発者ですませんが、

-(void)scrollViewDidScroll:(UIScrollView *)myScrollView { 
    CGPoint newCoord = CGPointMake((int)(myScrollView.contentOffset.x + myScrollView.frame.size.width/2) /50, (int)(myScrollView.contentOffset.y + myScrollView.frame.size.height/2) /50); 
    if(newCoord.x != currentCoord.x || newCoord.y != currentCoord.y) { 
     currentCoord = newCoord; 
     [self loadMapTiles]; 
    } 
} 
+1

'dispatch_apply(1、queue、...)'のポイントは何ですか?私はあなたが 'dispatch_async(queue、^(){...})'を望んだと思う。 – hypercrypt

+0

私がそれを行うなら、 'Collection が列挙されている間に突然変異を起こした。' ' scrollView非同期に正しくですか? – Hjalmar

+1

UIKit呼び出しはメインスレッド上にあるはずです – hypercrypt

答えて

4

CATiledLayerをご覧ください。マップの大きさに関わらず、好きなことを好きなやり方で行うことができます。また、ズームレベルごとに異なる画像を表示することもできます。

+0

これは素晴らしいですが、小さなタイルマップでこれをうまく活用するためのチュートリアルや良い例は見つかりませんか? PDFを使用しています。 – Hjalmar

1

...

でしばらく前のモバイルWeb開発の話だったので、メモリを割り当てて解放するのではなく、メモリを再利用することをお勧めします。

すべてのタイルに対して新しいUIImageViewを作成するのではなく、マップ全体が事前に割り当てられていて、マップがスクロールされたときにその中の画像を変更するだけで十分ですか?

1

おそらく、地図を描き、それをスクロールするために、scrollviewの代わりにCoreGraphicsとレイヤーを使ってみるべきでしょう。

0

WWDC 2010のビデオ「scrollviewsを使ったアプリケーションの設計」とそれに対応するサンプルコード「PhotoScroller」を見ると、scrollViewsの "view reuse"という大きなテクニックが学べます。 同じ名前のWWDC 2011ビデオは同じトリックの続きです。スクロールが遅いダウンを引き起こすことがバインドされている間

「可視領域にしなくなったビューは、新しいものを表示するために再利用および再配置されなければならない」

は、サブビューの追加と削除。代わりに、見えないものを再配置して新しいものを表示するだけです。スクロールの問題の

他の通常の原因は サブビュー上の任意の不透明度(shadowPathを設定せずに)

layer.cornerRadius layer.shadowです。

コアアニメーションを使用してデバイス上でコードを常にプロファイルします。

関連する問題