ตัวอย่างหนังสือข้อมูลหลักเพิ่มเซลล์ที่กำหนดเอง

ฉันได้ใช้แอปของฉันตามโปรเจ็กต์ตัวอย่าง Core Data Books ที่ Apple มอบให้ และฉันได้สร้างแต่ละเซลล์เป็นเซลล์แบบกำหนดเองซึ่งแสดงข้อมูลบางอย่างและทำงานได้อย่างน่าอัศจรรย์

อย่างไรก็ตาม ตอนนี้ฉันกำลังพยายามเพิ่มเซลล์ที่กำหนดเองเซลล์ที่สอง เป็นเซลล์เอกพจน์ซึ่งจะเป็นเซลล์แรกในตารางเสมอ จากนั้นผลลัพธ์ที่ดึงมาจากข้อมูลหลักทั้งหมดจะอยู่ต่ำกว่านั้น

ฉันได้ลองแล้ว:

- (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;
    }
}

พร้อมกับการเปลี่ยนแปลงอื่น ๆ เพื่อพยายามทำให้สิ่งต่าง ๆ ทำงานได้ ปัญหาเล็กน้อย

ประการแรก มุมมองโหลดได้ดี ฉันได้เซลล์ที่กำหนดเองของฉันที่ดัชนี 0 จากนั้นเซลล์ข้อมูลหลักของฉันจะโหลดต่ำกว่านั้น ปัญหาแรก เซลล์ข้อมูลหลักแรกสุดไม่ปรากฏให้เห็นเนื่องจากถูกซ่อนอยู่หลังเซลล์ที่กำหนดเองของฉัน แต่หากฉันแตะเซลล์นั้น ฉันจะได้รับมุมมองรายละเอียดสำหรับการป้อนข้อมูลหลักนั้น ดังนั้นฉันจึงต้องหาวิธีหยุดไม่ให้เซลล์ดังกล่าวอยู่หลังเซลล์ที่กำหนดเองนั้น

ฉันได้พยายามแก้ไขปัญหานี้แล้ว ตัวอย่างเช่น ดูเหมือนว่าจะสมเหตุสมผลที่ส่วนนี้:

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

ดังนั้น นี่เป็นเพียงการตั้งค่าเซลล์ให้เพียงพอสำหรับบันทึกข้อมูลหลักเท่านั้น และไม่ได้พิจารณาถึงเซลล์แบบกำหนดเองเพิ่มเติมนั้น ดังนั้นฉันจึงลองทำอะไรง่ายๆดังนี้:

return [sectionInfo numberOfObjects] + 1;

จากนั้นสิ่งนี้ส่งผลให้บรรทัดนี้ทำให้ฉันได้รับข้อขัดข้องและข้อผิดพลาดของดัชนีเกินขอบเขต:

GuestInfo *guest = [fetchedResultsController objectAtIndexPath:indexPath];

บรรทัดนั้นมาจากวิธี configurationCell ซึ่งตั้งค่าเซลล์บันทึกข้อมูลหลัก ฉันจึงค่อนข้างนิ่งงันว่าจะทำอย่างไร

ปัญหาถัดไป เมื่อฉันแก้ไขแอตทริบิวต์ของบันทึกข้อมูลหลักในมุมมองรายละเอียด การกลับไปที่มุมมองตาราง เซลล์ที่กำหนดเองของฉันไม่แสดงการเปลี่ยนแปลงใดๆ มันแสดงสถิติที่เกี่ยวข้องกับข้อมูลข้อมูลหลัก เฉพาะเซลล์อื่นๆ เท่านั้นที่ได้รับการอัปเดต

ความช่วยเหลือใดๆ จะได้รับการชื่นชมอย่างมาก และหากคุณต้องการดูโค้ดอีกต่อไปหรือต้องการคำอธิบายเพิ่มเติม โปรดแจ้งให้เราทราบ

แก้ไข:

รหัสเพิ่มเติมตามที่ร้องขอเพื่อช่วยฉัน นี่คือโค้ด 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 แหล่งที่มา
comment
คุณเปิดใช้งาน ARC หรือไม่? ถ้าไม่เช่นนั้น เซลล์ที่ส่งคืนโดย -tableView:cellForRowAtIndexPath: ควรได้รับการเผยแพร่โดยอัตโนมัติ   -  person AechoLiu    schedule 16.01.2012
comment
คุณใช้ NSFetchedResultController ดังนั้นคุณช่วยโพสต์รหัสเกี่ยวกับการกำหนดค่า fetchedResultController ได้ไหม และรหัสเกี่ยวกับ [fetchedResultsController actFetch:...] อย่างไรก็ตาม หลังจากเปลี่ยนคุณสมบัติของออบเจ็กต์ที่ได้รับการจัดการ คุณจะเรียก [tableView reloadData] เพื่ออัปเดตมุมมองตารางหรือไม่   -  person AechoLiu    schedule 16.01.2012
comment
ใช่ ฉันใช้ ARC การโทร [self.tableView reloadData] ช่วยแก้ไขปัญหาการโหลดข้อมูลในเซลล์ที่กำหนดเองเซลล์เดียวของฉันซ้ำ อย่างไรก็ตาม ยังคงต้องค้นหาเซลล์แปลก ๆ ที่ทับซ้อนกัน ฉันจะโพสต์โค้ดที่คุณร้องขอ   -  person Josh Kahane    schedule 16.01.2012
comment
บางทีวิธีที่ง่ายกว่าในการใส่มัน ฉันต้องการให้เซลล์ที่กำหนดเองของฉันอยู่ที่ดัชนี 0 ใน tableview จากนั้นข้อมูลหลักทั้งหมดก็ดึงผลลัพธ์มาติดตามหลังจากนั้น ปัจจุบันผลลัพธ์ข้อมูลหลักเริ่มต้นที่ดัชนี 0 ฉันจะปรับเปลี่ยนได้อย่างไร   -  person Josh Kahane    schedule 16.01.2012
comment
แต่ละส่วนต้องการเซลล์แบบกำหนดเองนี้หรือไม่ หากใช่ -tableView:numberOfRowsInSection: ควรส่งคืน `1+[sectionInfo numberOfObjects] และคุณต้องปรับเส้นทางดัชนีด้วยตนเองเมื่อส่งคืนเซลล์ด้วย fetechedResultController   -  person AechoLiu    schedule 17.01.2012
comment
นั่นเป็นกลอุบายขอบคุณ การปรับ indexPath อย่างเหมาะสมเมื่อจำเป็นหยุดข้อผิดพลาดเกินขอบเขตของดัชนีที่ฉันได้รับโดยการเพิ่มจำนวนแถวในส่วน   -  person Josh Kahane    schedule 17.01.2012


คำตอบ (1)


ฉันกำลังใช้ฟังก์ชันเดียวกันและการใช้ออฟเซ็ตกับโซลูชันของ indexPath @Toro ก็ใช้ได้ดี ไม่รู้ว่ามีวิธีที่ดีกว่านี้หรือเปล่า นี่คือการปรับตัวของผมสำหรับผู้ที่สนใจ

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

เพิ่มหนึ่งแถวเพิ่มเติมสำหรับเซลล์ที่กำหนดเองของฉัน ผลลัพธ์ที่ดึงมาของฉันไม่มีส่วน ดังนั้นฉันจึงทำงานได้ดี

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

วิธีการส่วนตัวสำหรับการปรับดัชนีเส้นทางเพื่อดึงวัตถุที่ถูกต้องจาก NsFetchedResultController

นี่คือวิธีที่ฉันใช้ adjustedIndexPath:

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