2

ここで立ち往生しています。ここで何が間違っているのかわかりません。私は目的cにかなり慣れていません。私のアプリケーションでは、UITableViewandを使用NSMutableArrayして RSS フィードからのデータを解析しています。ユーザーがテーブルビューのセグメント コントロールをクリックしたときに、テーブル全体を新しいデータで更新したいと考えています。テーブル ヘッダー セクションにセグメント コントロールを追加しました。セグメント インデックスが変更されたときに値を変更しても問題なく動作します。

問題は、セグメント コントロールをクリックすると、テーブル全体が更新されるのではなく、テーブルビューに新しい行が追加されることです。コードは次のとおりです。

- (void)addEarthquakesToList:(NSArray *)earthquakes
    {
    //NSInteger startingRow = [self.earthquakeList count];
    NSInteger earthquakeCount = [earthquakes count];
    NSMutableArray *indexPaths = [[NSMutableArray alloc] initWithCapacity:earthquakeCount];
    NSLog(@"%d",earthquakeCount);

    for (NSInteger row = 0; row < (earthquakeCount); row++)
    {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
        [indexPaths addObject:indexPath];
    }

    [self.earthquakeList addObjectsFromArray:earthquakes];
    [self.tableView  insertRowsAtIndexPaths:indexPaths
                           withRowAnimation:UITableViewRowAnimationAutomatic];
}

配列からすべてのオブジェクトを削除し、テーブルから行を削除するために次のこと[self.tableView reloadData];
も試しましたが、正しい行数が表示されません。

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init];

    for(unsigned int i = 0; i < [self.earthquakeList count]; i++)
    {
        [indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i inSection:0]];
    }

    //[self.tableView beginUpdates];
    [self.earthquakeList removeAllObjects];
    [self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
                          withRowAnimation:UITableViewRowAnimationFade];
    //[self.tableView endUpdates];
    //[self.tableView reloadData];
}

そして、これらは私のtableView DataSourceメソッドです:

- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
    // The number of rows is equal to the number of earthquakes in the array.
    return [self.earthquakeList count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *kEarthquakeCellID = @"EarthquakeCellID";
    citsTableViewCell *cell = (citsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:kEarthquakeCellID];

    //Get the specific earthquake for this row.
    citsFuelFinder *earthquake = (self.earthquakeList)[indexPath.row];
    [cell configureWithEarthquake:earthquake];
    return cell;
}

実際、セグメント コントロールに以下を含めようとすると、次のようになります。

- (void)segmentedControlHasChangedValue
{
    int product;
    product = fuelType.selectedSegmentIndex;

    switch (product)
    {
        case 0:
            productName=1;
            [locationManager startUpdatingLocation];
            break;

        case 1:
            productName=2;
            //[self.earthquakeList removeLastObject];
            if (![self.earthquakeList count])
            {
                [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:0]
                              withRowAnimation:UITableViewRowAnimationRight];
            }
            else
            {
                NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init];
                for(unsigned int i = 0; i < [self.earthquakeList count]; i++)
                {
                    [indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i
                                                                     inSection:0]];
                }
                //[self.tableView beginUpdates];
                //[self.earthquakeList removeAllObjects];
                [self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
                                      withRowAnimation:UITableViewRowAnimationFade];
                //[self.tableView endUpdates];
                [self.tableView reloadData];
                //[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
            }
            [locationManager startUpdatingLocation];
            break;

        case 2:
            productName=4;
            [locationManager startUpdatingLocation];
            break;

        case 3:
            productName=5;
            [locationManager startUpdatingLocation];
            break;

        default:
            break;
    }
}

次のエラーが表示されます。

キャッチされない例外 'NSInternalInconsistencyException' が原因でアプリを終了しています。理由: '無効な更新: セクション 0 の行数が無効です。更新後の既存のセクションに含まれる行数 (15) は、それに含まれる行数と等しくなければなりません更新前のセクション (15)、そのセクションから挿入または削除された行の数 (挿入 0、削除 15) のプラスまたはマイナス、およびそのセクションに移動された行またはセクションから移動された行の数 (移動された 0、移動された 0アウト)。' *First throw call stack: (0x2e332e83 0x3868f6c7 0x2e332d55 0x2ecdb0af 0x30c8a34d 0x30cb083f 0x6d2d9 0x30aebda3 0x30aebd3f 0x30aebd13 0x30ad7743 0x30bf7c59 0x30bf7a27 0x30cbca25 0x30aaf1a1 0x30ae69fd 0x30ae63ab 0x30abbd79 0x30aba569 0x2e2fdf1f 0x2e2fd3e7 0x2e2fbbd7 0x2e266471 0x2e266253 0x32fa02eb 0x30b1b845 0x6948d 0x38b88ab7)

どんな助けでも大歓迎です!

4

5 に答える 5

0

データ ソース配列に要素を追加する場合は、いいえ。テーブル ビューの行の数が自動的に更新されます。行を挿入する必要はありません。要素を挿入するだけです。メソッドを次のように実装します。

- (void)addEarthquakesToList:(NSArray *)earthquakes 
{
   [self.earthquakeList addObjectsFromArray:earthquakes];
   [self.tableview reloadData];
} 
于 2013-11-07T07:09:29.690 に答える
0

ええと、代わりに

[self.tableView  insertRowsAtIndexPaths:indexPaths
                       withRowAnimation:UITableViewRowAnimationAutomatic];

試す

[self.tableView  reloadRowsAtIndexPaths:indexPaths
                       withRowAnimation:UITableViewRowAnimationAutomatic];

とにかく....コードスニペットは、少なくとも私にとっては、問題を特定するにはまだ不十分です。

しかし、あなたが言ったので:
I want to refresh the whole table with new data when user click on the segment control in the tableview.

セグメントごとに異なるデータを表示する 4 つのセグメントを持つセグメント化された tableView を作成する必要がある場合は、次のようにします。

注: これは基本的な例です。特定のコードには準拠していませんが、indexPaths を操作するロジックや、配列から手動でオブジェクトを追加/削除するロジックを削除し、代わりにtableView reloadData適切に使用することをお勧めします。

- (void)viewDidLoad
{
    [super viewDidLoad];

    //declare NSArray *arrFirst, *arrSecond, *arrThird, *arrFourth, *arrSelected
    //in the .h file

    arrFirst = [[NSArray alloc] initWithObjects:@"eins",@"zwei",@"drei",@"vier",@"fünf",@"sechs", nil];
    arrSecond = [[NSArray alloc] initWithObjects:@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eigth",@"nine", nil];
    arrThird = [[NSArray alloc] initWithObjects:@"uno",@"dos",@"tres",@"cuatro",@"cinco", nil];
    arrFourth = [[NSArray alloc] initWithObjects:@"ek",@"do",@"teen",@"chaar",@"paach",@"che",@"saat", nil];

    arrSelected = arrFirst;
}

- (IBAction)mySegmentsAct:(UISegmentedControl *)sender
{
    switch (sender.selectedSegmentIndex)
    {
        case 0:
            arrSelected = arrFirst;
            break;
        case 1:
            arrSelected = arrSecond;
            break;
        case 2:
            arrSelected = arrThird;
            break;
        case 3:
            arrSelected = arrFourth;
            break;
        default:
            arrSelected = nil;
            break;
    }

    [myTableView reloadData];
}

-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
    return [arrSelected count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView
        cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
                                     reuseIdentifier:CellIdentifier];
    }
    cell.textLabel.text = (arrSelected)[indexPath.row];
    return cell;
}

単一の配列を使用してこれを行うこともできます。最初に古い配列の内容をフラッシュし、
arrSelected = nil
次に新しい要素をこの配列に入れ (何らかのロジックを使用するソースから)
、最後に:
myTableView reloadData.

于 2013-11-07T09:52:25.343 に答える
0

これらの置換を試して、後でフィードバックをお寄せください (特に、NSAssert がアプリを「クラッシュ」させた場合)。

- (void)addEarthquakesToList:(NSArray *)earthquakes
{
    // data checking
    NSAssert(self.earthQuakeList != nil, @"earthQuakeList cannot be nil!");
    NSAssert(self.tableView != nil, @"tableView cannot be nil!");
    NSAssert(earthquakes != nil, @"earthquakes cannot be nil!");

    // relevant implementation
    [self.earthquakeList addObjectsFromArray:earthquakes];
    [self.tableView reloadData];
}

- (void)segmentedControlHasChangedValue
{
    // data checking
    NSAssert(self.earthQuakeList != nil, @"earthQuakeList cannot be nil!");
    NSAssert(self.tableView != nil, @"tableView cannot be nil!");
    NSAssert(fuelType != nil, @"fuelType cannot be nil!");
    NSAssert(locationManager != nil, @"locationManager cannot be nil!");

    // relevant implementation
    switch (fuelType.selectedSegmentIndex)
    {
        case 0:
            productName=1; // what is this?
            [locationManager startUpdatingLocation];
            break;

        case 1:
            productName=2;
            [self.earthquakeList removeAllObjects];
            [locationManager startUpdatingLocation];
            break;

        case 2:
            productName=4;
            [locationManager startUpdatingLocation];
            break;
        case 3:
            productName=5;
            [locationManager startUpdatingLocation];
            break;

        default:
            break;
    }

    [self.tableView reloadData]; // if you want to change the data whenever the user changes the UISegmentedControl to any new value, leave this here.
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    // data checking
    NSAssert(self.earthQuakeList != nil, @"earthQuakeList cannot be nil!");
    NSAssert(self.tableView != nil, @"tableView cannot be nil!");

    // relevant implementation
    [self.earthquakeList removeAllObjects];
    [self.tableView reloadData];
}
于 2014-08-15T19:30:51.030 に答える