เซลล์ที่กำหนดเองใน UITableView จะไม่โหลดซ้ำอย่างถูกต้องหลังจากมีการเปลี่ยนแปลงข้อมูลในเซลล์

ฉันได้สร้างเซลล์ที่กำหนดเองใน UITableView สไตล์ถูกตั้งค่าเป็นกำหนดเอง ตัวระบุถูกตั้งค่าเป็น customCell อุปกรณ์เสริมถูกตั้งค่าเป็นรายละเอียด เนื้อหา Table View ได้รับการตั้งค่าเป็น Dynamic Prototypes

ตารางจะเต็มไปด้วยข้อมูลจากข้อมูลหลักและปรากฏอย่างสมบูรณ์แบบเมื่อปรากฏขึ้นครั้งแรก เมื่อผู้ใช้แตะไอคอนรายละเอียดในเซลล์ ส่วนต่อไปยังมุมมองใหม่จะปรากฏขึ้นเพื่อให้ผู้ใช้สามารถแก้ไขข้อมูลในเซลล์และบันทึกลงในข้อมูลหลักได้ เมื่อผู้ใช้แก้ไขเสร็จแล้วและแตะปุ่มบันทึก มุมมองจะกลับไปที่ UITableView แต่เซลล์ที่เพิ่งแก้ไขจะปรากฏเป็นเซลล์ 'พื้นฐาน' ไม่ใช่เซลล์แบบกำหนดเอง ถ้าฉันแตะที่เซลล์ มันจะไฮไลท์และเนื้อหาเซลล์แบบกำหนดเองจะปรากฏเหนือเนื้อหาเซลล์พื้นฐาน

ดูเหมือนว่าฉันจะไม่สามารถแก้ไขปัญหานี้ได้ ใครสามารถแนะนำบางสิ่งบางอย่าง?

นี่คือส่วนของ prepareForSegue ที่ส่งไปยังตัวควบคุมมุมมองการแก้ไข:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell*)sender {

if ([[segue identifier]isEqualToString:@"editPunchItemSegue"]) {
// DEFINE SEGUE DESTINATION
UINavigationController *navigationController = segue.destinationViewController;
EditPunchItemViewController *editPunchItemViewController = (EditPunchItemViewController*)navigationController.topViewController;

NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
Punchitem *editPunchItem = (Punchitem*)[self.fetchedResultsController objectAtIndexPath:indexPath];

editPunchItemViewController.editPunchitem = editPunchItem;

และตอนนี้ใน View Controller ปลายทางซึ่งมีการแก้ไขข้อมูลหลัก นี่คือส่วนหนึ่งของเมธอด saveButtonPressed:

 if  ([_editSaveButton.title isEqualToString:@"Save"]) {
    NSLog(@"Save Button has been PRESSED");

    editPunchitem.punchitemRoomNumber = _editPunchitemRoomNumberField.text;
    editPunchitem.punchitemDescription = _editPunchitemDescriptionField.text;
    editPunchitem.punchitemLocation = _editPunchitemLocationField.text;
    editPunchitem.punchitemRoomName = _editPunchitemRoomNameField.text;
    editPunchitem.punchitemDate = _editPunchitemDateField.text;

    // SAVE TO MANAGE OBJECT CONTEXT!
    [super saveAndDismiss];
}

มีข้อเสนอแนะอะไรบ้าง?

นี่คือ cellForRowAtIndex ของฉันใน TableViewController

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));

    static NSString *CellIdentifier = @"customCell";

//  USING CUSTOM PROTOTYPE CELL:
    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    Punchitem *punchitem = [self.fetchedResultsController objectAtIndexPath:indexPath];

//  USING CUSTOM PROTOTYPE CELL:
    cell.cellLocationLabel.text = punchitem.punchitemLocation;
    cell.cellDescriptionLabel.text = punchitem.punchitemDescription;
    cell.cellRoomNameLabel.text = punchitem.punchitemRoomName;

    return cell;
}

บันทึกและยกเลิกเป็นส่วนหนึ่งของคลาสย่อย นี่คือวิธีการ:

-(void) saveAndDismiss {

    NSError *error = nil;
    if ([self.managedObjectContext hasChanges]) {
        if (![self.managedObjectContext save:&error]) {  //SAVE FAILED
            NSLog(@"YOUR SAVE FAILED! %@", [error localizedDescription]);
        } else {
            NSLog(@"SAVE SUCCEEDED!");
        }
    }

    [self dismissViewControllerAnimated:YES completion:nil];
}

person Jupiter869    schedule 02.03.2014    source แหล่งที่มา
comment
การบันทึกและยกเลิกทำหน้าที่อะไร และโปรดแสดง cellAtRowIndex ดูเหมือนว่ามีบางอย่างกำลังเขียนทับกระดานเรื่องราวของคุณ   -  person meda    schedule 02.03.2014
comment
ฉันเพิ่งเพิ่ม cellForRowAtIndex ของฉันในการโพสต์ดั้งเดิมของฉัน   -  person Jupiter869    schedule 02.03.2014
comment
ลองใช้เซลล์ต้นแบบ xib   -  person Oleg Sobolev    schedule 03.03.2014
comment
พบวิธีแก้ปัญหาที่ดีมากสำหรับการแชทนี้   -  person Sameeksha Kumari    schedule 15.06.2014


คำตอบ (4)


คุณลองโหลดตารางใหม่เมื่อคุณกลับมาจาก EditPunchItemViewController หรือไม่

ใส่ใน master viewController :

- (void)viewWillAppear:(BOOL)animated {
   if (self.tableView) {
        [self.tableView reloadData];
    }
}
person Armand DOHM    schedule 02.03.2014
comment
ใช่ ฉันมีบรรทัดนั้นใน viewWillAppear ของ TableViewController น่าเสียดายที่มันไม่ได้ช่วยอะไร - person Jupiter869; 02.03.2014

คุณมีบางอย่างเช่นนี้

[self.tableView beginUpdates];

ถ้าใช่ คุณจะเรียกสิ่งนี้เมื่อเสร็จแล้วแน่นอน

[self.tableView endUpdates];

เวลาส่วนใหญ่เราใช้สิ่งนี้กับ NSFetchedResultsController...

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView beginUpdates];
}
...
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}
person Armand DOHM    schedule 02.03.2014
comment
ใช่ ขอบคุณสำหรับคำแนะนำนี้ แต่ฉันมีทั้งสองวิธีรวมอยู่ในโค้ดของฉันแล้ว - person Jupiter869; 02.03.2014

ตัวเลือกสุดท้าย คุณต้องทำการดีบักแบบมีเงื่อนไข...

ทั้งหมดใน ViewController หลักของคุณ:

1) เพิ่มคุณสมบัติ

@property (strong,nonatomic) NSIndexPath *DEBUGindexPath;

2) ตั้งค่า DEBUGindexPath ใน

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell*)sender {

if ([[segue identifier]isEqualToString:@"editPunchItemSegue"]) {
...
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
DEBUGindexPath = indexPath;
...

3) เพิ่มเบรกพอยต์ใน

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

แก้ไขเบรกพอยต์เพื่อกำหนดเงื่อนไข :

(self.DEBUGindexPath.row == indexPath.row) && (self.DEBUGindexPath.section == indexPath.section)

อย่าตั้งค่าดำเนินการต่อโดยอัตโนมัติ...

ตกลง ตอนนี้เรียกใช้แอปของคุณ เมื่อคุณจะกลับจาก EditPunchItemViewController จุดพักควรทริกเกอร์สำหรับแถวที่เลือกเท่านั้น ทีละขั้นตอนเพื่อตรวจสอบว่าคุณพบบางสิ่งบางอย่างหรือไม่

person Armand DOHM    schedule 02.03.2014

มุมมองกลับสู่ UITableView แต่เซลล์ที่เพิ่งแก้ไขปรากฏเป็นเซลล์ 'พื้นฐาน' ไม่ใช่เซลล์ที่กำหนดเอง

ดู cellForRowAtIndexPath อย่างละเอียด โดยมีเงื่อนไขต่อไปนี้:

    //USING CUSTOM PROTOTYPE CELL:
    CustomTableViewCell *cell =
                    [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomTableViewCell alloc]
                             initWithStyle:UITableViewCellStyleDefault 
                           reuseIdentifier:CellIdentifier];
    }

เมื่อเซลล์ไม่มีค่า คุณจะตั้งค่าสไตล์เป็น UITableViewCellStyleDefault แต่คุณลืมตั้งค่าประเภทอุปกรณ์เสริมผ่านโค้ด

ดังนั้นเพียงตรวจสอบให้แน่ใจว่าตั้งค่าประเภทอุปกรณ์เสริมในคำสั่ง if เช่นนี้:

    //USING CUSTOM PROTOTYPE CELL:
    CustomTableViewCell *cell =
                    [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomTableViewCell alloc]
                             initWithStyle:UITableViewCellStyleDefault 
                           reuseIdentifier:CellIdentifier];
        //Set accessory to Detail
        cell.accessoryType = UITableViewCellAccessoryDetailButton;
    }

นี่คือรายการสไตล์ทั้งหมด:

typedef enum : NSInteger {
   UITableViewCellAccessoryNone,
   UITableViewCellAccessoryDisclosureIndicator,
   UITableViewCellAccessoryDetailDisclosureButton,
   UITableViewCellAccessoryCheckmark,
   UITableViewCellAccessoryDetailButton
} UITableViewCellAccessoryType;
person meda    schedule 02.03.2014
comment
ฉันไม่เข้าใจ. ฉันกำลังใช้เซลล์ที่กำหนดเอง เมื่อโหลดมุมมองตาราง ฉันจะได้รับมุมมองพื้นฐานแทนมุมมองที่กำหนดเอง ฉันจะเพิ่มบรรทัด cell.accessoryType = UITableViewCellAccessoryDetailButton ได้ที่ไหนเพื่อให้แน่ใจว่าเซลล์ที่กำหนดเองปรากฏขึ้นและไม่ใช่เซลล์พื้นฐาน ฉันควรใช้อย่างอื่นที่ไม่ใช่ UITableViewCellStyleDefault หรือไม่ - person Jupiter869; 03.03.2014
comment
@ Jupiter869 ฉันขอโทษที่ฉันไม่ชัดเจน ดูการแก้ไขของฉัน - person meda; 03.03.2014
comment
น่าเสียดายที่สิ่งนี้ไม่มีผล เมื่อฉันกลับจาก EditView ไปยัง TableView เซลล์จะปรากฏเป็นเซลล์พื้นฐานโดยมีข้อมูลหนึ่งบรรทัดอยู่ในนั้น แทนที่จะเป็นเซลล์แบบกำหนดเองที่ฉันตั้งค่าไว้ในกระดานเรื่องราว ถ้าฉันคลิกในเซลล์ มันจะไฮไลต์และทั้ง 'Basic' และ 'customCell จะปรากฏทับกัน ดูเหมือนว่าเซลล์ 'พื้นฐาน' อยู่ด้านบนสุดของ 'เซลล์ที่กำหนดเอง' มันทำให้ฉันงุนงงและหงุดหงิดมาก - person Jupiter869; 03.03.2014
comment
ภาพนี้แสดง tableView เมื่อโหลดครั้งแรก: imgur.com/sPoazwi - ภาพถัดไปนี้แสดง tableView หลังจากวินาที เซลล์ได้รับการแก้ไขแล้ว โปรดสังเกตว่าเซลล์แสดงรูปแบบเซลล์พื้นฐาน: imgur.com/TSFct3J - รูปภาพสุดท้ายแสดงสิ่งที่เกิดขึ้นเมื่อฉันคลิก เซลล์ที่สอง เซลล์แบบกำหนดเองจะปรากฏที่ด้านบนของเซลล์พื้นฐาน: imgur.com/uHtSoon - person Jupiter869; 03.03.2014
comment
@ Jupiter869 คุณกำลังใช้เซลล์ต้นแบบอยู่ใช่ไหม? - person meda; 03.03.2014
comment
tableView ของฉันถูกตั้งค่าเป็น Dynamic Prototypes ในสตอรี่บอร์ด - person Jupiter869; 03.03.2014
comment
ให้เราสนทนาต่อในการแชท - person meda; 03.03.2014