2010-03-02 52 views
25

Tôi biết câu hỏi này đã được hỏi trước đây và tôi đã xem câu trả lời cho this question. Tuy nhiên, tôi vẫn còn bối rối về cách thực hiện sắp xếp lại với một UITableView trong một dự án Core Data. Những gì tôi biết là tôi cần có thuộc tính "displayOrder" trong Thực thể để theo dõi thứ tự các mục và tôi cần phải liệt kê tất cả các đối tượng trong kết quả tìm nạp và đặt thuộc tính displayOrder của chúng.Dữ liệu lõi UITableView sắp xếp lại

Trong mã đã cho trong câu hỏi tôi đã liên kết, phương thức ủy nhiệm xem bảng gọi phương thức như thế này [self FF_fetchResults]; và mã cho phương thức đó không được cung cấp để khó biết chính xác nó là gì.

Có mã mẫu nào chứng minh điều này không? Điều đó sẽ đơn giản hơn để xem xét hơn là chia sẻ một lượng lớn mã.

Cảm ơn

+0

Bạn đã thử đoạn code liên kết? Nếu bạn đang sử dụng bộ điều khiển kết quả tìm nạp, bạn có thể không cần phải làm gì cả. Phương thức đó chỉ tìm nạp lại các đối tượng (bây giờ sắp xếp đã thay đổi). – gerry3

+0

Cảm ơn, tôi sẽ thử. Có cần phải lấy lại các đối tượng sau khi lệnh đã thay đổi không? – indragie

+0

Bạn không cần phải nếu bạn đang sử dụng bộ điều khiển kết quả tìm nạp (và có mã tấm nồi hơi để cập nhật chế độ xem bảng khi bộ điều khiển kết quả tìm nạp thay đổi). – gerry3

Trả lời

56

Tôi không chắc chắn bạn đang gặp khó khăn nào (dựa trên nhận xét) ... nhưng đây là đề xuất của tôi. DisplayOrder chỉ là một thuộc tính đơn giản trên lớp NSManagedObject. Nếu bạn có thể lưu một đối tượng được quản lý, thì bạn sẽ có thể hoàn thành tính năng này. Trước tiên, hãy thực hiện NSManagedObject đơn giản:

@interface RowObj : NSManagedObject 
{ 
} 

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

Tiếp theo, chúng tôi cần có bản sao cục bộ của dữ liệu được hiển thị trong chế độ xem bảng. Tôi đã đọc qua các ý kiến ​​bạn đã thực hiện và tôi không thực sự chắc chắn nếu bạn đang sử dụng FetchedResultsController hay không. Đề xuất của tôi sẽ là bắt đầu đơn giản và chỉ sử dụng một tableviewcontroller bình thường, nơi bạn cập nhật dữ liệu hàng bất cứ khi nào người dùng thay đổi thứ tự hiển thị ... sau đó lưu thứ tự khi người dùng chỉnh sửa xong.

Giao diện cho tableviewcontoller này sẽ trông như thế này:

@interface MyTableViewController : UITableViewController { 
    NSMutableArray *myTableViewData; 
} 

@property(nonatomic,retain) NSMutableArray *myTableViewData; 

@end 

Tiếp theo, chúng ta cần phải nạp dữ liệu xem bảng trong phương pháp viewWillAppear:

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

Có 2 điều đang xảy ra ở đây ... (tôi sẽ giải thích editButtonItem sau) đầu tiên là chúng ta cần lấy dữ liệu của chúng tôi từ CoreData. Khi tôi phải làm điều này tôi có một số loại trợ giúp (gọi nó là những gì bạn muốn) đối tượng làm công việc. Một phương pháp tìm kiếm điển hình sẽ trông như sau:

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

Bây giờ bạn có dữ liệu, bây giờ bạn có thể đợi người dùng chỉnh sửa bảng. Đó là nơi [self editButtonItem] được phát. Đây là tính năng tích hợp trả về mục nút thanh chuyển đổi tiêu đề và trạng thái được kết hợp giữa Chỉnh sửa và Xong. Khi người dùng nhấn nút đó, nó sẽ gọi phương thức setEditing: animated::

Để cập nhật thứ tự hiển thị, bạn cần ghi đè phương thức setEditing trên lớp UITableViewController. Nó sẽ trông giống như sau:

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

Chúng tôi không phải làm gì khi người dùng đang ở chế độ chỉnh sửa ... chúng tôi chỉ muốn lưu khi họ đã nhấn nút "Xong". Khi người dùng kéo một hàng trong bảng của bạn, bạn có thể cập nhật theo thứ tự hiển thị của bạn bằng cách ghi đè các phương pháp canMoveRowAtIndexPath và moveRowAtIndexPath:

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

Một lần nữa, lý do tôi không cập nhật giá trị DisplayOrder ở đây là vì người sử dụng vẫn còn trong là chế độ chỉnh sửa...chúng tôi không biết nếu người dùng đã chỉnh sửa xong VÀ họ thậm chí có thể hủy những gì họ đã làm bằng cách không nhấn nút "Xong".

EDIT

Nếu bạn muốn xóa một dòng bạn cần phải ghi đè tableView: commitEditingStyle: forRowAtIndexPath và làm điều gì đó như thế này:

- (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]; 
    } 
} 
+0

Cảm ơn câu trả lời chi tiết, tôi sẽ dùng thử. – indragie

+0

Chắc chắn, hãy cho tôi biết nếu bạn có bất kỳ vấn đề nào ... đây là cơ bản word-4-word từ một triển khai hoạt động từ một trong các ứng dụng của tôi vì vậy nó sẽ giúp bạn hoàn thành nó. –

+0

Điều gì về việc xóa các hàng? Có điều gì đặc biệt cần được thực hiện ở đó để làm việc với điều này không? – indragie

Các vấn đề liên quan