2010-01-10 50 views
6

我最近剛剛完成了Stephen Kochan在Objective-C 2.0中的編程以及Erica Sadun的iPhone Cookbook的部分內容,這是iPhone開發和編程的新手。剛剛閱讀本網站上回答的問題幫助了我很多,所以我非常感謝所有用戶。現在我正在開發我的第一款iPhone應用程序,並且正在取得良好進展,除了一件讓我難以置信的事情。可重新排序的UITableView,每部分最大行數

我在使用UITableView時遇到了一些麻煩。基本上,我有一個表格,每個部分最多需要6行,沒有最小值(除非1行部分的行被刪除,在這種情況下,部分與它一起)。該表也可以由用戶重新排序。當用戶將一行拖入一個已經有最多6個分配行的部分時,我希望該部分的最後一行將'budge'排序成爲下一部分的第一行。

至於實現這個,我的第一個想法是調用tableView:moveRowAtIndexPath:toIndexPath:中的一個方法,它將遍歷循環中的各個部分,確保它們中沒有一個具有7+行,根據需要調整數組,然後使用[myTable beginUpdates]塊刪除並插入所需的行。這一切看起來像什麼(注:我的陣列結構是:數組(表)>陣列(段)>詞典(項目)):

-(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!"); 
} 

問題是,當我運行它,它總是拋出例外;它給我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.)Attempted to create two animations for cell,這取決於我正在嘗試哪種調整。至於那些調整,我也嘗試使用reloadSections:withRowAnimation:,當然還有一個簡單的[editTable reloadData]。我試着將調用放在相應的TableView委託/數據源方法中,包括targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:,以及AppleView指南中提到的有點神祕的willMoveToRowAtIndexPath:fromIndexPath:方法,但在別的地方並不存在。

我在谷歌,本網站和蘋果的文檔中搜索了所有解決方案,但無濟於事。

所以,簡單地說一下我的問題,最好的方法是什麼?我忽略了一些明顯的東西嗎?或者,我的實施概念是否從根本上來說是有缺陷的?

在此先感謝您的幫助!任何有識之士將不勝感激。

- 德魯R.胡德

UPDATE:繼他在他的回答評論喬丹的建議,我已經驗證實際編輯數據源正在經歷正常。當表格編輯塊執行時,我現在總是得到錯誤Attempt to create two animations for cell(通過常識和斷點驗證時間)。所以我在編輯塊中做錯了什麼。目前的代碼完全如上所示。想法?

回答

0

所以,我終於解決了這個問題,並認爲我會發布我在這裏爲了後代而做的。這很簡單,真的:我只是將表中行的實際插入和刪除移到了一個單獨的方法中,然後在延遲後調用它。從一開始就已經很清楚了,約旦幫助我確認了在桌面上執行更新時發生的問題,而不是實際更改數據的過程。因此,這裏的該訣竅代碼:

-(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!"); 
} 

所有我需要做執行,這是添加該片段到我moveRowAtIndexPath:方法:

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

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

} 

所以我希望這有助於人誰可能有這個問題在未來。感謝喬丹和所有看過這個問題的人。 :)

2

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

我相信你需要更新數據源,然後才能刪除行中的任何部分。因此,在此代碼中,在刪除之前,從Table_Array_Macro(我認爲這是您的數據所在的位置)刪除該行。

+0

感謝您的答覆。它是,我做了 - 上面說:[[TABLE_ARRAY_MACRO objectAtIndex:i] removeLastObject]; [[TABLE_ARRAY_MACRO objectAtIndex:(i + 1)] insertObject:lastIcon atIndex:0] ;.爲了澄清,我的數據源是一個數組數組(每個節一個數組),在這些數組中是包含表單元格實際信息的字典。 – FrigginGuy 2010-01-10 16:18:54

+0

嘗試添加一個NSLog來統計前後的記錄數。我很確定那裏有不匹配的地方。這就是錯誤溝通的原因。 – Jordan 2010-01-10 17:49:44

+0

我遵循你的建議,我的數組正在根據需要進行更改。我確信這些計數和內容都能正確對應。一切都結束了。我現在得到的唯一錯誤是'嘗試爲單元格創建兩個動畫',所以看起來我的問題出現在我的編輯塊中。 : - / – FrigginGuy 2010-01-12 02:32:27