2010-01-10 29 views
6

Tôi mới sử dụng chương trình và nhà phát triển iPhone nói chung, gần đây đã hoàn thành Lập trình của Stephen Kochan trong Mục tiêu-C 2.0 và một phần của Sách điện tử iPhone của Erica Sadun. Chỉ cần đọc các câu hỏi được trả lời trên trang web này đã giúp tôi rất nhiều, vì vậy tôi nợ một lời cảm ơn lớn đến tất cả người dùng của nó. Bây giờ tôi đang làm việc trên ứng dụng iPhone đầu tiên của mình và đang tiến triển tốt, tiết kiệm cho một điều khiến tôi bối rối.UITableView có thể sắp xếp lại với số lượng tối đa hàng trên một phần

Tôi gặp sự cố với UITableView. Về cơ bản, tôi có một bảng cần tối đa 6 hàng cho mỗi phần, không có tối thiểu (ngoại trừ nếu hàng của phần 1 hàng bị xóa, trong trường hợp phần này đi cùng với nó). Bảng cũng có thể được sắp xếp lại bởi người dùng. Khi người dùng kéo một hàng vào một phần đã có tối đa 6 hàng được phân bổ, tôi muốn hàng dưới cùng của phần đó sắp xếp 'chồi' xuống để trở thành hàng trên cùng của phần tiếp theo. Để thực hiện điều này, suy nghĩ đầu tiên của tôi là gọi một phương thức trong tableView:moveRowAtIndexPath:toIndexPath: sẽ đi qua các phần trong vòng lặp, đảm bảo rằng không có ai trong số họ có 7 hàng trở lên, điều chỉnh mảng nếu cần và sau đó sử dụng [myTable beginUpdates] khối để xóa và chèn các hàng được yêu cầu. Đây là những gì tất cả những gì trông giống như (lưu ý: cấu trúc mảng của tôi là: Array (Bảng)> Mảng (Phần)> Từ điển (Items)):

-(void) tableView: (UITableView *) tableView moveRowAtIndexPath: (NSIndexPath *) from toIndexPath: (NSIndexPath *) to 
{ 
// Get the dictionary object for the icon. 
NSMutableDictionary *theIcon = [[[TABLE_ARRAY_MACRO objectAtIndex: from.section] objectAtIndex: from.row] mutableCopy]; 

// Now remove it from the old position, and insert it in the new one. 
[[TABLE_ARRAY_MACRO objectAtIndex: from.section] removeObjectAtIndex: from.row]; 
[[TABLE_ARRAY_MACRO objectAtIndex: to.section] insertObject: theIcon atIndex: to.row]; 

if ([[TABLE_ARRAY_MACRO objectAtIndex: to.section] count] > 6) 
      [self budgeRowsAtSection: to.section]; 

// Now we're done with the dictionary. 
[theIcon release]; 

if (PM_DEBUG_MODE) 
    NSLog(@"Pet moved!"); 
} 



-(void) budgeRowsAtSection: (NSUInteger) section 
{ 
    if (PM_DEBUG_MODE) 
    NSLog(@"Budging rows..."); 

    // Set up an array to hold the index paths of the cells to move. 
    NSMutableArray *budgeFrom = [[NSMutableArray alloc] init]; 
    NSMutableArray *budgeTo = [[NSMutableArray alloc] init]; 

    // Start at the current section, and enumerate down to the nearest page with < 6 items. 
    int i = section; 

while (i < [TABLE_ARRAY_MACRO count]) { 

    if (PM_DEBUG_MODE) 
     NSLog(@"Attempting to budge rows in section %i!", i); 

    if ([[TABLE_ARRAY_MACRO objectAtIndex: i] count] > 6) { 

    // Grab the last object, and move it to the beginning of the next array. 
    NSMutableDictionary *lastIcon = [[[PET_ICON_DATA objectAtIndex: i] lastObject] mutableCopy]; 

    [[TABLE_ARRAY_MACRO objectAtIndex: i] removeLastObject]; 
    [[TABLE_ARRAY_MACRO objectAtIndex: (i + 1)] insertObject: lastIcon atIndex: 0]; 

    // Create an index path, and reflect the changes in the table. 
    [budgeFrom addObject: [NSIndexPath indexPathForRow: 6 inSection: i]]; 
    [budgeTo addObject: [NSIndexPath indexPathForRow: 0 inSection: (i + 1)]]; 

    // Now we're done with the icon. 
    [lastIcon release]; 

} 

if (PM_DEBUG_MODE) 
     NSLog(@"Rows budged for section %i!", i); 

++i; 

} 

    if (PM_DEBUG_MODE) 
    NSLog(@"From cells: %@\nTo cells: %@", budgeFrom, budgeTo); 

    if (PM_DEBUG_MODE) 
    NSLog(@"Data budged! Updating table..."); 

    [editTable beginUpdates]; 
    [editTable deleteRowsAtIndexPaths: budgeFrom withRowAnimation: UITableViewRowAnimationBottom]; 
    [editTable insertRowsAtIndexPaths: budgeTo withRowAnimation: UITableViewRowAnimationTop]; 
    [editTable endUpdates]; 

    [budgeFrom release]; 
    [budgeTo release]; 

    if (PM_DEBUG_MODE) 
    NSLog(@"Row budge done!"); 
} 

Vấn đề là khi tôi chạy này, nó lúc nào cũng ném một ngoại lệ; nó cung cấp cho tôi Invalid update: number of rows in section after update must be equal to number of rows before update, + or - the number inserted or deleted (etc.) hoặc Attempted to create two animations for cell, tùy thuộc vào tinh chỉnh mà tôi đang thử. Đối với những tinh chỉnh đó, tôi cũng đã thử sử dụng reloadSections:withRowAnimation: và tất nhiên là [editTable reloadData] đơn giản. Tôi đã thử thực hiện cuộc gọi đến phương thức này trong các phương thức nguồn dữ liệu/đại biểu TableView có liên quan, bao gồm targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: và phương thức willMoveToRowAtIndexPath:fromIndexPath: hơi bí ẩn được đề cập trong hướng dẫn của Apple trên TableViews, nhưng không tồn tại ở nơi khác.

Tôi đã tìm kiếm trên tất cả các trang web của Google, trang web này và tài liệu của Apple để tìm bất kỳ giải pháp nào, nhưng không có kết quả.

Vì vậy, để đặt câu hỏi của tôi một cách đơn giản, cách tốt nhất để giải quyết vấn đề này là gì? Có một số điều hiển nhiên mà tôi đang xem không? Hoặc là khái niệm thực hiện của tôi về cơ bản là thiếu sót từ khi bắt đầu?

Cảm ơn bạn đã trợ giúp! Bất kỳ cái nhìn sâu sắc sẽ được nhiều đánh giá cao.

- Drew R. Hood

UPDATE: Sau lời khuyên Jordan từ bình luận của mình về câu trả lời của mình, tôi đã xác minh rằng các chỉnh sửa thực tế để các nguồn dữ liệu đang trải qua một cách chính xác. Bây giờ tôi liên tục nhận được lỗi Attempt to create two animations for cell khi khối chỉnh sửa bảng thực thi (thời gian đó được xác minh bằng ý nghĩa thông thường và điểm ngắt). Vì vậy, tôi đang làm điều gì đó sai trong khối chỉnh sửa của mình. Mã hiện tại cho chính xác như được hiển thị ở trên. Ý tưởng?

Trả lời

0

Vì vậy, cuối cùng tôi đã giải quyết được vấn đề và nghĩ rằng tôi sẽ đăng những gì tôi đã làm ở đây vì lợi ích của hậu thế. Nó khá đơn giản, thực sự: Tôi chỉ cần di chuyển chèn thực tế và xóa các hàng trong bảng ra một phương pháp riêng biệt, mà sau đó tôi gọi sau một sự chậm trễ. Nó đã được rõ ràng từ đầu, và Jordan đã giúp tôi xác nhận, rằng vấn đề đã xảy ra khi thực hiện các bản cập nhật trên bảng chính nó, hơn là trong quá trình thực sự thay đổi dữ liệu. Vì vậy, đây là đoạn code mà đã làm các trick:

-(void) performBudges 
{ 
if (PM_DEBUG_MODE) 
    NSLog(@"Performing budge animations..."); 

[editTable beginUpdates]; 
[editTable deleteRowsAtIndexPaths: budgeFrom withRowAnimation: UITableViewRowAnimationRight]; 
[editTable insertRowsAtIndexPaths: budgeTo withRowAnimation: UITableViewRowAnimationRight]; 
[editTable endUpdates]; 

[editTable performSelector: @selector(reloadData) withObject: nil afterDelay: 0.5]; 

[reloadedSections release]; 

[budgeFrom release]; 
[budgeTo release]; 

if (PM_DEBUG_MODE) 
    NSLog(@"Budges completed!"); 
} 

Và tất cả tôi phải làm gì để thực hiện điều này là thêm đoạn này vào moveRowAtIndexPath: phương pháp của tôi:

if ([[PET_ICON_DATA objectAtIndex: to.section] count] > 6) { 

    [self budgeRowsAtSection: to.section]; 
    [self performSelector: @selector(performBudges) withObject: nil afterDelay: 1.0]; 

} 

Vì vậy, tôi hy vọng điều này sẽ giúp bất cứ ai có thể có vấn đề này trong tương lai. Cảm ơn Jordan và tất cả những ai đã xem câu hỏi này. :)

2

[editTable startedUpdates]; [editTable deleteRowsAtIndexPaths: budgeFrom withRowAnimation: UITableViewRowAnimationBottom];
[editTable insertRowsAtIndexPaths: budgeTo withRowAnimation: UITableViewRowAnimationTop];
[editTable endUpdates];

Tôi tin rằng bạn cần cập nhật DataSource trước khi bạn thực sự xóa Hàng trong bất kỳ phần nào bạn đang xóa nó.Vì vậy, trong mã này, trước khi bạn xóa, xóa hàng từ Table_Array_Macro (mà tôi nghĩ là nơi dữ liệu của bạn).

+0

Cảm ơn bạn đã trả lời. Đó là, và tôi đã làm —— ở trên nơi nó nói: [[TABLE_ARRAY_MACRO objectAtIndex: i] removeLastObject]; [[TABLE_ARRAY_MACRO đối tượngAtIndex: (i + 1)] insertObject: lastIcon atIndex: 0] ;. Để làm rõ, nguồn dữ liệu của tôi là một mảng các mảng (một mảng cho mỗi phần), và trong các mảng đó là các từ điển chứa thông tin thực tế cho các ô của bảng. – FrigginGuy

+0

Thử thêm NSLog để đếm số lượng bản ghi, trước và sau. Tôi khá chắc chắn có một sự không phù hợp ở đó. Đó là những gì lỗi đang giao tiếp. – Jordan

+0

Tôi đã làm theo lời khuyên của bạn và mảng của tôi đang được thay đổi khi cần thiết. Tôi đảm bảo rằng cả số lượng và nội dung đều tương ứng. Mọi thứ đều kiểm tra. Lỗi duy nhất tôi nhận được bây giờ là 'Cố gắng để tạo ra hai hình ảnh động cho điều' tế bào, do đó, nó xuất hiện vấn đề của tôi xảy ra trong khối chỉnh sửa của tôi. : - / – FrigginGuy

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