Contoh Buku Data Inti Tambahkan Sel Khusus

Saya mendasarkan aplikasi saya pada proyek contoh Buku Data Inti yang disediakan Apple dan saya telah menjadikan setiap sel sebagai sel khusus yang menampilkan data tertentu, bekerja secara ajaib.

Namun, sekarang saya mencoba menambahkan sel khusus kedua. Ini adalah sel tunggal yang akan selalu menjadi sel pertama dalam tabel, lalu semua hasil yang diambil dari data inti berada di bawahnya.

Saya sudah mencoba seperti ini:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{    
    if (indexPath.row == 0) 
    {
        static NSString *CellIdentifier = @"statsCell";

        GuestStatsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
        {
            cell = [[GuestStatsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }

        //Configure the cell.
        [self configureStatsCell:cell];

        return cell;
    }
    else
    {
        static NSString *CellIdentifier = @"guestCell";

        customGuestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
        {
            cell = [[customGuestCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }

        // Configure the cell.
        [self configureGuestCell:cell atIndexPath:indexPath];

        return cell;
    }
}

Seiring dengan beberapa perubahan lain untuk mencoba dan membuat semuanya berfungsi. Beberapa masalah.

Pertama, tampilan dimuat dengan baik, saya mendapatkan sel khusus saya di indeks 0 dan kemudian sel data inti saya dimuat di bawahnya. Masalah pertama, sel data inti pertama tidak terlihat karena tersembunyi di balik sel khusus saya, tetapi jika saya mengetuknya, saya mendapatkan tampilan detail untuk entri data inti tersebut. Jadi saya perlu mencari cara bagaimana menghentikannya terjadi di balik sel khusus itu.

Saya telah mencoba memperbaikinya, misalnya, tampaknya logis bahwa potongan ini:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}

Jadi, ini hanya mengatur sel yang cukup untuk rekaman data inti dan tidak memperhitungkan sel khusus tambahan tersebut. Jadi saya mencoba sesuatu yang sederhana seperti ini:

return [sectionInfo numberOfObjects] + 1;

Kemudian ini menghasilkan baris ini yang menyebabkan saya mendapatkan error crash dan indeks di luar batas:

GuestInfo *guest = [fetchedResultsController objectAtIndexPath:indexPath];

Baris tersebut berasal dari metode konfigurasiCell yang mengatur sel rekaman data inti. Jadi saya cukup bingung apa yang harus dilakukan.

Masalah selanjutnya, ketika saya mengedit atribut rekaman data inti apa pun dalam tampilan detail, kembali ke tampilan tabel sel khusus saya tidak menunjukkan perubahan apa pun. Ini menampilkan statistik yang berkaitan dengan info data inti. Hanya sel lain yang diperbarui.

Bantuan apa pun akan sangat kami hargai, dan jika Anda perlu melihat kode lagi atau memerlukan penjelasan lebih lanjut, beri tahu saya.

Sunting:

Lebih banyak kode seperti yang diminta untuk membantu saya. Ini adalah kode NSFetchedController.

- (NSFetchedResultsController *)fetchedResultsController 
{

    if (fetchedResultsController != nil) 
    {
        return fetchedResultsController;
    }

    // Create and configure a fetch request with the Book entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"GuestInfo" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];

    // Create the sort descriptors array.
    NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastName" ascending:YES];
    NSSortDescriptor *firstNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:lastNameDescriptor, firstNameDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    // Create and initialize the fetch results controller.
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"displayOrder" cacheName:@"Root"];

    self.fetchedResultsController = aFetchedResultsController;
    fetchedResultsController.delegate = self;

    // Memory management.
    //No releasing with ARC!

    return fetchedResultsController;
}    


/**
 Delegate methods of NSFetchedResultsController to respond to additions, removals and so on.
 */

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureGuestCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            [self.tableView reloadData];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];
}

person Josh Kahane    schedule 15.01.2012    source sumber
comment
Apakah Anda mengaktifkan ARC? Jika tidak, sel yang dikembalikan oleh -tableView:cellForRowAtIndexPath: harus dirilis secara otomatis.   -  person AechoLiu    schedule 16.01.2012
comment
Anda menggunakan NSFetchedResultController. Jadi, bisakah Anda memposting kode tentang konfigurasi FetchedResultController ? Dan kode tentang [fetchedResultsController performFetch:...]. Ngomong-ngomong, setelah mengubah atribut objek yang dikelola, apakah Anda memanggil [tableView reloadData] untuk memperbarui tampilan tabel?   -  person AechoLiu    schedule 16.01.2012
comment
Ya, saya menggunakan ARC. Memanggil [self.tableView reloadData] membantu menyelesaikan masalah memuat ulang data pada satu sel khusus saya. Namun masih perlu menyelesaikan sel ganjil yang tumpang tindih, saya akan memposting kode yang Anda minta.   -  person Josh Kahane    schedule 16.01.2012
comment
Mungkin cara yang lebih sederhana untuk menjelaskannya. Saya ingin sel khusus saya di indeks 0 di tampilan tabel. Kemudian semua data inti diambil hasilnya menyusul setelah itu. Saat ini hasil data inti mulai dari indeks 0, bagaimana cara menyesuaikannya?   -  person Josh Kahane    schedule 16.01.2012
comment
Apakah setiap bagian memerlukan sel khusus ini? Jika ya, -tableView:numberOfRowsInSection: harus mengembalikan `1+[sectionInfo numberOfObjects]. Dan Anda perlu menyesuaikan jalur indeks secara manual saat mengembalikan sel dengan fetechedResultController.   -  person AechoLiu    schedule 17.01.2012
comment
Itu berhasil, terima kasih. Menyesuaikan IndexPath dengan tepat ketika diperlukan menghentikan kesalahan indeks di luar batas yang saya dapatkan dengan menambah jumlah baris di bagian.   -  person Josh Kahane    schedule 17.01.2012


Jawaban (1)


Saya menerapkan fungsi yang sama dan menggunakan offset dengan solusi indexPath @Toro berfungsi dengan baik. Tidak tahu apakah ada cara yang lebih baik atau tidak, berikut penyesuaian saya bagi yang berminat.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects] + 1;
}

Tambahkan satu baris tambahan untuk sel khusus saya, hasil yang saya ambil tidak memiliki bagian jadi ini berfungsi dengan baik.

- (NSIndexPath *)adjustedIndexPath:(NSIndexPath *)indexPath
{
    NSIndexPath *newPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
    return newPath;
}

metode pribadi untuk menyesuaikan jalur indeks untuk mengambil objek yang tepat dari NsFetchedResultController.

Berikut cara yang saya terapkan adjustedIndexPath:

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
person sarunw    schedule 25.01.2012