2012-04-17 23 views
15

你會認爲這很容易。使用這段代碼,我可以檢查表中的多行,但我想要的是一次只檢查一行。如果用戶選擇不同的行,那麼我希望舊行只是自動取消選中。不知道該怎麼做。這是我的代碼:UITableView選中對號一次只有一行

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

[tableView deselectRowAtIndexPath:indexPath animated:YES]; 


UITableViewCell *theCell = [tableView cellForRowAtIndexPath:indexPath]; 

if (theCell.accessoryType == UITableViewCellAccessoryNone) { 
    theCell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } 

    else if (theCell.accessoryType == UITableViewCellAccessoryCheckmark) { 
    theCell.accessoryType = UITableViewCellAccessoryNone; 
    } 
} 

感謝您的任何幫助,你可以借!

+1

對於那些被正確回答的問題,您應該點擊旁邊的複選標記以接受正確答案。 – 2012-04-17 14:51:36

回答

22

最好的辦法是設置的cellForRowAtIndexPath附件類型和使用didSelectRowAtIndexPath方法只哪個路徑應該選擇記錄,然後調用reloadData。

+1

此解決方案的唯一問題是您將失去取消選擇行動畫。只需重新加載其他可見單元格。 – 2012-04-17 16:03:48

+1

我絕對選擇正確的第一個和稍後......如果有必要。 :-) – 2012-04-17 16:08:16

+1

再次感謝您! reloadData是使事情發揮作用的關鍵。非常感謝您的洞察力。 – Jupiter869 2012-04-17 21:09:02

17

您可以創建一個新變量來跟蹤在didSelectRowAtIndex處選擇的索引。

int selectedIndex; 

在你的cellForRowAtIndexPath

if(indexPath.row == selectedIndex) 
{ 
    cell.accessoryType = UITableViewCellAccessoryCheckmark; 
} 
else 
{ 
    cell.accessoryType = UITableViewCellAccessoryNone; 
} 

,並在您didSelectRowAtIndex

selectedIndex = indexPath.row; 
[tableView reloadData]; 
+0

請聲明爲NSINTEGER而不是int – Arun 2016-07-19 09:25:24

4

簡單的方法就是保存所選IndexPath,並檢查它的cellForRowAtIndexPath。

附着是代碼:

步驟1:初始化selectedIndexPath selectedIndexPath = [[NSIndexPath的alloc] INIT];

第2步:在的cellForRowAtIndexPath

if([selectedIndexPath isEqual:indexPath]){ 
    [checkMark setHidden:NO]; 
} else { 
    [checkMark setHidden:YES]; 
} 

第3步:在didSelectRowAtIndexPath方法

selectedIndexPath = indexPath; 
[tableView reloadData]; 

它應該工作試試這個恩喬伊:)

8

你並不需要重新加載的tableView 。

請參見下面的代碼:

聲明一個NSIndexPath lastSelectedIndexPath變量類

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    if(lastSelectedIndexPath) { 

     UITableViewCell *lastCell = [tableView cellForRowAtIndexPath:lastSelectedIndexPath]; 
     [lastCell setAccessoryView:nil]; 
    } 

    UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:currentIndexPath]; 
    [currentCell setAccessoryView:UITableViewCellAccessoryCheckmark]; 

    lastSelectedIndexPath = indexPath; 
} 
+0

有誰知道如何使用NSUserDeafults保存所選行的狀態?我一直在尋找一種簡單的方法來做到這一點。我發現的所有解決方案都相當複雜,而且對於我的項目來說,這會讓我的代碼更加混亂。 – 2014-03-08 06:31:34

+0

@Borges你能解釋一下你的問題嗎?一個細胞的狀態究竟意味着什麼? – 2014-03-09 07:28:01

71
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; 
} 

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; 
} 

Swift版本將是:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark 
} 

func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { 
    tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None 
} 

Swift 3更新

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark 
} 

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 
    tableView.cellForRow(at: indexPath)?.accessoryType = .none 
} 
+1

最好的解決方案!謝謝! – 2014-09-10 17:23:21

+0

@ThomásC。同意! – mikemike396 2014-09-30 15:04:01

+2

這不關心可重用性。小心。 – p0lAris 2015-05-18 22:24:39

0
Swift iOS 

    var checkedIndexPath : NSIndexPath? 

    // table row which row was selected 
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath!) { 
     tableView.deselectRowAtIndexPath(indexPath, animated: true) 

     println("Section #\(indexPath.section)! You selected cell #\(indexPath.row)!") 

     if (self.checkedIndexPath != nil) { 
      var cell = tableView.cellForRowAtIndexPath(self.checkedIndexPath!) 
      cell?.accessoryType = .None 
     } 

     var cell = tableView.cellForRowAtIndexPath(indexPath) 
     cell?.accessoryType = .Checkmark 

     self.checkedIndexPath = indexPath 

    }// end tableView 
+0

它崩潰時, 'checkedIndexPath' 是不是在TableView中VisibleCells 如果(self.checkedIndexPath!=無){VAR 細胞= tableView.cellForRowAtIndexPath(self.checkedIndexPath!) 細胞?.accessoryType = .None } 如果不在可見單元格中,單元格爲零 – umakanta 2015-09-15 12:34:54

1

試試這個:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    if indexPath.section == 1 { 
     // un-select the older row 
     if let selected = self.LastSelected { 
      tableView.cellForRowAtIndexPath(selected)?.accessoryType = .None 
     } 

     // select the new row 
     tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = UITableViewCellAccessoryType.Checkmark 
     self.LastSelected = indexPath 
    } 
} 
10

您不需要(也不應該)剛剛刷新每次選擇後的表。

關於如何管理選擇列表,Apple有很好的documentation。有關示例,請參見清單6-3。

這或多或少與其他一些答案相同,但我想我會添加更多的細節。

你想要做的是將當前選定的IndexPath保存到一個變量,並使用didSelectRowAtIndexPath中的刪除舊的複選標記。這也是您將添加新複選標記的地方。

您還需要確保還設置/取消設置cellForRowAtIndexPath中的複選標記,否則如果列表很大並且單元格被重用,它將看起來像選擇了多行。這是一些其他答案的問題。

見SWIFT 2.0下面的例子:

// for saving currently seletcted index path 
var selectedIndexPath: NSIndexPath? = NSIndexPath(forRow: 0, inSection: 0) // you wouldn't normally initialize it here, this is just so this code snip works 
// likely you would set this during cellForRowAtIndexPath when you dequeue the cell that matches a saved user selection or the default 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    // this gets rid of the grey row selection. You can add the delegate didDeselectRowAtIndexPath if you want something to happen on deselection 
    tableView.deselectRowAtIndexPath(indexPath, animated: true) // animated to true makes the grey fade out, set to false for it to immediately go away 

    // if they are selecting the same row again, there is nothing to do, just keep it checked 
    if indexPath == selectedIndexPath { 
     return 
    } 

    // toggle old one off and the new one on 
    let newCell = tableView.cellForRowAtIndexPath(indexPath) 
    if newCell?.accessoryType == UITableViewCellAccessoryType.None { 
     newCell?.accessoryType = UITableViewCellAccessoryType.Checkmark 
    } 
    let oldCell = tableView.cellForRowAtIndexPath(selectedIndexPath!) 
    if oldCell?.accessoryType == UITableViewCellAccessoryType.Checkmark { 
     oldCell?.accessoryType = UITableViewCellAccessoryType.None 
    } 

    selectedIndexPath = indexPath // save the selected index path 

    // do whatever else you need to do upon a new selection 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) 
    // if this is the currently selected indexPath, set the checkmark, otherwise remove it 
    if indexPath == selectedIndexPath { 
     cell.accessoryType = UITableViewCellAccessoryType.Checkmark 
    } else { 
     cell.accessoryType = UITableViewCellAccessoryType.None 
    } 
} 
+0

這是一個很好的答案。 – damianesteban 2016-04-27 16:33:13

+0

這個答案很奇妙,但是它假設'selectedIndexPath'被初始化了,不是嗎?我的意思是,如果在初始化表視圖時沒有默認值,'didSelectRowAtIndexPath'應該嘗試展開'selectedIndexPath'並設置值 – matteodv 2017-08-31 14:54:32

+0

@matteodv,在我的代碼片段中我對第三行有一個評論,當您將與保存的用戶選擇或缺省值相匹配的單元出列時,可能會在cellForRowAtIndexPath期間設置此值。這是否回答你的問題? – jeffjv 2017-09-01 20:13:46

0

在雨燕2.0我用這個:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

    if((lastSelectedIndexPath) != nil) { 
     let lastCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath) 
     lastCell?.accessoryType = UITableViewCellAccessoryType.None 
    } 

    let currentCell = tableView.cellForRowAtIndexPath(indexPath) 
    currentCell?.accessoryType = UITableViewCellAccessoryType.Checkmark 

    lastSelectedIndexPath = indexPath 

} 
+0

lastSelectedIndexPath如何初始化和管理? as lastSelectedIndexPath永遠不可以爲零 – 2016-03-02 07:37:04

+0

var lastSelectedIndexPath:NSIndexPath? = NSIndexPath(forRow:0,inSection:0) – 2016-03-02 08:34:41

+0

'var lastSelectedIndexPath:NSIndexPath!'在開始時爲零,但之後,我檢查if是否爲nil,並且在函數結尾處我做了:'lastSelectedIndexPath = indexPath' – Dasoga 2016-03-02 14:42:26

1

在斯威夫特,以下作品完美:

lastSelectedIndexPath = NSIndexPath(forRow: 1, inSection: 0)//Row will be the previous selected row 


    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
{ 
    let cell:LabelsSelectionCell = tableView.dequeueReusableCellWithIdentifier("LabelsSelectionCell", forIndexPath: indexPath) as! LabelsSelectionCell 
    cell.setCellLael(labelOptionsArray[indexPath.row]) 
    if lastSelectedIndexPath == indexPath 
    { 
     cell.setCellCheckedStatus(true) 
    } 
    return cell 
} 
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
{ 
    if let _ = lastSelectedIndexPath 
    { 
     let lastCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath!) as! LabelsSelectionCell 
     lastCell.setCellCheckedStatus(false) 
    } 
    let currentCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(indexPath) as! LabelsSelectionCell 
    currentCell.setCellCheckedStatus(true) 

    lastSelectedIndexPath = indexPath 

    tableView.deselectRowAtIndexPath(indexPath, animated: true) 
} 
0

我的辦法是取消其他細胞選擇期間:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = .... 

    if condition { 
     cell.accessoryType = .checkmark 
     tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.bottom) 
    } else { 
     cell.accessoryType = .none 
    } 

    return cell 
} 

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    for row in 0...tableView.numberOfRows(inSection: 0) { 
     if row == indexPath.row {continue} 
     tableView.deselectRow(at: IndexPath(row: row, section: 0), animated: true) 
    } 

    if let cell = tableView.cellForRow(at: indexPath) { 
     cell.accessoryType = .checkmark 
    } 
} 

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 
    let cell = tableView.cellForRow(at: indexPath) 
    cell?.accessoryType = .none 
} 
1

對於斯威夫特3以下爲我工作:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    tableVIew.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark 
} 

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 
    tableVIew.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none 
} 
+0

不工作的人。:( – Ashik 2017-09-15 17:36:46

+0

嘗試使用ckeckmark單元格樣式 – Tarik 2017-09-25 12:24:52

0

這裏就是我來了,當我有這個問題。
此代碼在最新版本的Swift中實施,截至今天...
欲瞭解更多信息和/或擴展文件,請查看該片段的Github Gist

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {  
    if let sip = selectedIndex { 
     tableView.deselectRow(at: sip, animated: false) 
    } 
    selectedIndex = indexPath 
} 

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 
    if selectedIndex?.row == indexPath.row { 
     selectedIndex = nil 
    } 
} 
0

測試,並解決了嘗試這個它完美地工作

添加爲全局變量

var selectedIndexPath = NSIndexPath(row: 0, section: 0) 

在didselect方法添加此

 // old one check off 
     if indexPath != selectedIndexPath as IndexPath { 
      let oldCell = categorytable.cellForRow(at: selectedIndexPath as IndexPath) 
      if oldCell?.accessoryView != nil { 
       oldCell?.accessoryView = nil 
      } 
      else { 
       let imageName = "checkmark" 
       let image: UIImageView = UIImageView(image: UIImage(named: imageName)) 
       cell.accessoryView = image 
      } 
     } 
     // the new one on 

     if cell.accessoryView == nil { 
      let imageName = "checkmark" 
      let image: UIImageView = UIImageView(image: UIImage(named: imageName)) 
      cell.accessoryView = image 
     } 
     else { 
      cell.accessoryView = nil 
     }