1

OS XでNSTableViewを使用して、iPhone電話アプリの最近の呼び出しTableViewの機能をかなり厳密に模倣しようとしています。望ましい機能は、ボタンをクリックすると、TableViewが最近のすべての呼び出しの表示からサブセットの表示に切り替わることです。逃した電話の中で、行の出現と消失がアニメーション化された iPhone で見られるアニメーションが必要です。

私はビューベースの NSTableView を使用しており、手動のデータソースとビューコントローラーのデリゲートを使用して非常に簡単に接続しています (ココアバインディングを使用していません)。

「逃した」呼び出しのサブセットを表示するために行を削除しようとする場合を除いて、すべてが機能しています。TableView のデータ ソースである NSMutableArray を再構築してから reloadData を呼び出すと、完全に機能します。しかし、それではアニメーションが得られません。以下は、TableView とデータ ソース NSMutableArray が完全に同期し、TableView のコンテンツが正しいが、アニメーションがない、アニメーション化されていないバージョンです。

- (IBAction)showMissed:(id)sender {    
  NSMutableIndexSet *indices = [NSMutableIndexSet indexSet];
  Call *call;

  for (call in callsArray) {
    if (!call.missed) {
      [indices addIndex:[callsArray indexOfObject:call]];
    }
  }
  if ([indices count] > 0) {
    [callsArray removeObjectsAtIndexes:indices];
    [self.recentsTableView reloadData];
  }
}

NSTableViewremoveRowsAtIndexes:indices withAnimation:メソッドを使用して必要なアニメーションを取得しようとすると、非常に奇妙な動作が発生します。アニメーション化された showMissed メソッドは次のとおりです。

- (IBAction)showMissed:(id)sender {    
  NSMutableIndexSet *indices = [NSMutableIndexSet indexSet];
  Call *call;

  for (call in callsArray) {
    if (!call.missed) {
      [indices addIndex:[callsArray indexOfObject:call]];
    }
  }
  if ([indices count] > 0) {
    [callsArray removeObjectsAtIndexes:indices];
    [self.recentsTableView removeRowsAtIndexes:indices withAnimation:NSTableViewAnimationSlideUp];
  }
}

メソッドのアニメーション バージョンで使用しているロジックは、Apple のTableViewPlaygoundサンプル コードから引き出されています。

このコードを実行すると、2 つの奇妙な結果が得られます。まず、TableView は「逃した」呼び出しだけを表示するのではなく、正しい行数を表示します (つまり、TableView の行数は、逃したとマークされた Call オブジェクトの数と同じです) が、行に表示される実際のオブジェクトは次のとおりです。見逃したものと見逃していないものがあります。

さらに奇妙なのは、アニメーション化されたバージョンが実行された後、callsArray にすべての Call オブジェクトが含まれており、[callsArray removeObjectsAtIndexes:indices];ステートメントがまったく存在しないかのように見えることです。どういうわけか、removeRowsAtIndexes:indices withAnimation:メソッドがデータソース配列の内容をいじり、全体を狂わせているようです。

FWIW、私のアニメーション化された showAll メソッドは、基本的に を使用して上記の逆であり、insertRowsAtIndexes:indices withAnimation:完全に機能しているようです。

私は何を間違っていますか?

4

1 に答える 1

1

データ ソース配列と tableView の間の同期のどこかで何らかの破損があったに違いありません。メソッドの先頭に reloadData 呼び出しを追加して修正しました。修正された showMissed メソッドは次のとおりです。

- (IBAction)showMissed:(id)sender {    
  NSMutableIndexSet *indices = [NSMutableIndexSet indexSet];
  Call *call;

  [self.recentsTableView reloadData];

  for (call in callsArray) {
    if (!call.missed) {
      [indices addIndex:[callsArray indexOfObject:call]];
    }
  }
  if ([indices count] > 0) {
    [callsArray removeObjectsAtIndexes:indices];
    [self.recentsTableView removeRowsAtIndexes:indices withAnimation:NSTableViewAnimationSlideUp];
  }
}
于 2012-06-03T18:40:55.067 に答える