2009-01-28 34 views

回答

14

在這裏,我們做了我們的繁重工作。

- (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
     toIndexPath:(NSIndexPath *)toIndexPath 
{ 
    NSLog(@"move from:%d to:%d", fromIndexPath.row, toIndexPath.row); 
    // fetch the object at the row being moved 
    NSString *r = [rows objectAtIndex:fromIndexPath.row]; 

    // remove the original from the data structure 
    [rows removeObjectAtIndex:fromIndexPath.row]; 

    // insert the object at the target row 
    [rows insertObject:r atIndex:toIndexPath.row]; 
    NSLog(@"result of move :\n%@", [self rows]); 
} 

由於這是一個基本示例,因此讓所有行都可以移動。

- (BOOL)tableView:(UITableView *)tableView 
canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 
    return YES; 
} 
+0

當removeObjectAtIndex被調用,將減少該對象的引用計數(並可能導致它被釋放)?我認爲exchangeObjectAtIndex:withObjectAtIndex :(如@dreamlax所示)更安全。 – 2009-01-28 04:34:10

+0

順便說一句,如果你正在回答你自己的問題,我認爲這是一個很好的形式,使它成爲一個維基。 – 2009-01-28 04:34:55

+0

@KristopherJohnson`exchangeObjectAtIndex:withObjectAtIndex:`在這種情況下不適用。它具有不同於`tableView:moveRowAtIndexPath:toIndexPath:`所需的語義。 – Benjohn 2015-09-16 22:23:32

0

NSMutableArray有一個方法叫exchangeObjectAtIndex:withObjectAtIndex:

+3

我試過這個,但行爲不同。該表不交換行,它刪除一行,然後將其插入到不同的位置。如果我使用這種方法,那麼表和後備存儲在每次移動時都會失去同步。 – 2009-01-28 14:00:39

11

以上都不是。 在原始的發佈代碼中,tableview將會崩潰,因爲它會刪除仍然在使用的數據,甚至在更正之後,由於表格執行「重新排列」的方式,數組將沒有正確的數據。

exchangeObjectAtIndex:withObjectAtIndex:根據tableview中如何實現自身的重新排列

爲什麼重新排列陣列將無法正常工作? 因爲當用戶選擇一個表格單元格來重新排列它時,該單元格不會與它們正在移動的單元格交換。他們選擇的單元格被插入新的行索引,然後原始單元格被刪除。至少這是用戶看起來的樣子。

解決方案: 由於tableview實現重新排列的方式,我們需要執行檢查以確保我們添加和刪除正確的行。 我把這段代碼放在一起很簡單,對我來說非常完美。

使用的原貼代碼數據爲例:


- (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
     toIndexPath:(NSIndexPath *)toIndexPath 
{ 
    NSLog(@"move from:%d to:%d", fromIndexPath.row, toIndexPath.row); 
    // fetch the object at the row being moved 
    NSString *r = [rows objectAtIndex:fromIndexPath.row]; 

     // checks to make sure we add and remove the right rows 
    if (fromIndexPath.row > toIndexPath.row) { 

     // insert the object at the target row 
     [rows insertObject:r atIndex:toIndexPath.row]; 

     // remove the original from the data structure 
     [rows removeObjectAtIndex:(fromIndexPath.row + 1)]; 
    } 
    else if (fromIndexPath.row < toIndexPath.row) { 

     // insert the object at the target row 
     [rows insertObject:r atIndex:(toIndexPath.row + 1)]; 

     // remove the original from the data structure 
     [rows removeObjectAtIndex:(fromIndexPath.row)]; 

    } 

} 

如果你花一點時間,看一看在重排期間發生了什麼的實現代碼如下,你就會明白爲什麼我們添加了1就是我們沒有。

我很新的Xcode,所以我知道有可能是一個更簡單的方法來做到這一點,或者代碼可以簡化....只是試圖幫助我在哪裏可以因爲它帶我幾小時來弄清楚。希望這能節省一些時間!

5

根據蘋果的文檔,以及我自己的經驗,這是一些簡單的代碼,工作得很好:

NSObject *tempObj = [[self.rows objectAtIndex:fromIndexPath.row] retain]; 
[self.rows removeObjectAtIndex:fromIndexPath.row]; 
[self.rows insertObject:tempObj atIndex:toIndexPath.row]; 
[tempObj release]; 
0

找到打破我的頭靠在一個簡單的實施後此討論...邁克爾Berding解決方案是對我來說最適合蘋果的方式,只記得在使用ARC時刪除保留和釋放。因此,一個更簡潔的解決方案

NSObject *tempObj = [self.rows objectAtIndex:fromIndexPath.row]; 
[self.rows removeObjectAtIndex:fromIndexPath.row]; 
[self.rows insertObject:tempObj atIndex:toIndexPath.row]; 
相關問題