iphone - UITableView Core Data reordering



objective-c cocoa-touch (1)

أعلم أن هذا السؤال قد طُرح من قبل ، وألقيت نظرة على الإجابة على هذا السؤال . ومع ذلك ، ما زلت مرتبكًا حول كيفية تنفيذ إعادة الترتيب باستخدام UITableView في مشروع البيانات الأساسية. ما أعلمه هو أنني بحاجة إلى سمة "displayOrder" في الكيان لتعقب ترتيب العناصر ، ولست بحاجة إلى التعداد من خلال جميع الكائنات في النتائج التي تم إحضارها وتعيين سمة displayOrder الخاصة بهم.

في الكود المعطى في السؤال الذي ارتبط به ، تستدعي طريقة تفويض عرض الجدول طريقة مثل [self FF_fetchResults]; ، ولم يتم إعطاء رمز لهذه الطريقة حتى من الصعب معرفة ما هو بالضبط.

هل هناك أي رمز عينة يوضح هذا؟ سيكون من الأسهل النظر إليه من مشاركة أجزاء كبيرة من التعليمات البرمجية.

شكر

https://ffff65535.com


لست متأكداً من أي جزء تواجهه مشكلة (استناداً إلى التعليقات) ... ولكن هنا هو اقتراحي. يعد displayOrder مجرد سمة بسيطة في فئة NSManagedObject. إذا كان بإمكانك حفظ كائن مُدار ، فستتمكن من إنهاء هذه الميزة. دعونا أولا اتخاذ NSManagedObject بسيطة:

@interface RowObj :  NSManagedObject  
{
}

@property (nonatomic, retain) NSString *rowDescription;
@property (nonatomic, retain) NSNumber *displayOrder;

بعد ذلك ، نحتاج إلى الحصول على نسخة محلية من البيانات التي يتم عرضها في Tableview. لقد قرأت التعليقات التي قمت بإجرائها وأنا لست متأكداً إذا كنت تستخدم FetchedResultsController أم لا. سيكون اقتراحي لبدء بسيط وعادل استخدام tableviewcontroller العادي حيث تقوم بتحديث بيانات الصف كلما قام المستخدم بتغيير ترتيب العرض ... ثم حفظ الترتيب عند الانتهاء من تحرير المستخدم.

ستبدو واجهة هذا tableviewcontoller بالشكل التالي:

@interface MyTableViewController : UITableViewController {
    NSMutableArray *myTableViewData;
}

@property(nonatomic,retain) NSMutableArray *myTableViewData;

@end 

بعد ذلك ، نحتاج إلى تحميل بيانات عرض الجدول في طريقة viewWillAppear:

- (void)viewWillAppear:(BOOL)animated {
    myTableViewData = [helper getRowObjects]; // insert method call here to get the data
    self.navigationItem.leftBarButtonItem = [self editButtonItem];
}

هناك شيئان يحدثان هنا ... (سأشرح editButtonItem فيما بعد) الأول هو أننا بحاجة للحصول على بياناتنا من CoreData. عندما يكون لدي للقيام بذلك لدي نوع من المساعد (استدعاء ما تريد) كائن القيام بهذا العمل. تبدو طريقة البحث النموذجية كما يلي:

- (NSMutableArray*) getRowObjects{
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"RowObj" inManagedObjectContext:[self managedObjectContext]];
    [request setEntity:entity];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [request setSortDescriptors:sortDescriptors];
    [sortDescriptors release];
    [sortDescriptor release];

    NSError *error;
    NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
    if (mutableFetchResults == nil) {
        // Handle the error.
    }
    [request release];
    return mutableFetchResults;
}

الآن وبعد أن أصبحت لديك بياناتك ، يمكنك الآن الانتظار حتى يقوم المستخدم بتحرير الجدول. هذا هو المكان الذي يأتي فيه [self editButtonItem] . هذه ميزة مضمنة تقوم بارجاع عنصر زر شريط يقوم بتبديل عنوانه والحالة المصاحبة له بين Edit و Done. عندما يقوم المستخدم بالضغط على هذا الزر ، سوف يستدعي الأمر setEditing: animated: method:

لتحديث ترتيب العرض ، يجب تجاوز طريقة setEditing على فئة UITableViewController. يجب أن يبدو شيء من هذا القبيل:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [myTableView setEditing:editing animated:animated];
    if(!editing) {
        int i = 0;
        for(RowObj *row in myTableViewData) {
            row.displayOrder = [NSNumber numberWithInt:i++];
        }
        [helper saveManagedObjectContext]; // basically calls [managedObjectContext save:&error];
    }
}

لا يتعين علينا القيام بأي شيء عندما يكون المستخدم في وضع التحرير ... نحن نريد فقط حفظ بمجرد الضغط على زر "تم". عندما يسحب أحد المستخدمين صفًا في الجدول ، يمكنك تحديث ترتيب العرض عن طريق تجاوز canMoveRowAtIndexPath والانتقال إلى أساليب RowAtIndexPath:

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    return true;
}

(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {

    RowObj *row = [myTableViewData objectAtIndex:sourceIndexPath.row];
    [myTableViewData removeObjectAtIndex:sourceIndexPath.row];
    [myTableViewData insertObject:row atIndex:destinationIndexPath.row];
}

مرة أخرى ، السبب في عدم تحديث قيمة displayOrder هنا هو أن المستخدم لا يزال في وضع التحرير ... لا نعرف ما إذا كان المستخدم قد تم تحريره أم لا ، بل يمكنهم حتى إلغاء ما قاموا به من عدم ضرب زر "تم".

تصحيح

إذا كنت تريد حذف صف ما ، فيجب تجاوز tableView: commitEditingStyle: forRowAtIndexPath وفعل شيء كالتالي:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the managed object at the given index path.
        RowObj *row = [myTableViewData objectAtIndex:indexPath.row];
        [helper deleteRow:row];

        // Update the array and table view.
        [myTableViewData removeObjectAtIndex:indexPath.row];
        [myTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
    }   
}




core-data