2009-11-17 20 views
26

我很困惑一些關於設置表格視圖單元格附件。UITableViewCell附件類型檢查點擊&設置其他未選中

我已經在我的表固定兩個部分

  • 首頁
  • 辦公室

我想是因爲遵循....

  • 當用戶點擊任意的單元格
  • 單元格被選中&
    • 我想設置檢查(設置-checked抽頭細胞的UITableViewCell的附件類型)
  • 以及所有其他細胞的附件類型現在應該設置爲
    • uitable觀察室附件類型無

我試過下面的代碼。但是我發現indexpath.row & indexpath.section是隻讀屬性。

// Override to support row selection in the table view. 
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  
    [tblProfileView deselectRowAtIndexPath:indexPath animated:YES]; 
    int i,max; 
    UITableViewCell *x; NSIndexPath *tt; 

    for(i=0;i<[tblProfileView numberOfRowsInSection:0];i++) 
    { 
     tt.row=i; tt.section=0; 
     x=[tblProfileView cellForRowAtIndexPath:]; 
     [x setAccessoryType:UITableViewCellAccessoryNone]; 
    } 
    for(i=0;i<[tblProfileView numberOfRowsInSection:1];i++) 
    { 
     tt.row=i; tt.section=1; 
     x=[tblProfileView cellForRowAtIndexPath:tt]; 
     [x setAccessoryType:UITableViewCellAccessoryNone]; 
    } 

    x=[tblProfileView cellForRowAtIndexPath:indexPath]; 
    [x setAccessoryType:UITableViewCellAccessoryCheckmark]; 
    // Navigation logic may go here -- for example, create and push another view controller. 
    // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil]; 
    // [self.navigationController pushViewController:anotherViewController animated:YES]; 
    // [anotherViewController release]; 
} 

回答

48

我會跟蹤數據應當檢查和更改的tableView細胞:didSelectRowAtIndexPath方法:和更新數據在的tableView檢查:的cellForRowAtIndexPath:像這樣:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    // do usual stuff here including getting the cell 

    // determine the data from the IndexPath.row 

    if (data == self.checkedData) 
    { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } else { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } 

    return cell; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    // determine the selected data from the IndexPath.row 

    if (data != self.checkedData) { 
     self.checkedData = data; 
    } 

    [tableView reloadData]; 
} 
+1

由於您調用reloadData(根據您的數據可能很昂貴),因此這不是馬上行動。你可以簡單地:let cell = tableView.cellForRowAtIndexPath(indexPath) cell?.accessoryType =(yourTest)? .Checkmark:.None – Max 2016-03-21 12:44:32

+0

你實際上不得不做幾乎兩者。直接按照Max指出的那樣進行更新,並在cellForRowAtIndexPath中配置單元格,或者在滾動列表時將單元格狀態混淆。 – marsbear 2016-08-18 18:49:58

+1

哦,並實現didDeselectRowAtIndexPath以及你可以再次取消選中單元格。 – marsbear 2016-08-18 18:51:00

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

    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath]; 

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


} 

還需要去除的cellForRowAtIndexPath對號附件

if ([selectedOptionsArray indexOfObject:cell.textLabel.text] != NSNotFound) { 
    cell.accessoryType = UITableViewCellAccessoryCheckmark; 
}else{ 
    cell.accessoryType = UITableViewCellAccessoryNone; 
} 
+1

這與OP要求的內容不同。沒有提及允許多個或零選擇。當其中一個打開時,必須關閉。您的解決方案可讓用戶自行切換一行或多行,並且推測可能是selectedOptionsArray存儲了多個選定選項,而不僅僅是一個請求。 – Craig 2011-12-13 03:56:39

+1

@craig是的,你是現貨。但我使用這段代碼來切換我的應用程序的選項(行)。我認爲這可能是有用的,有些基於gerry3的片段,但我沒有使用[tableview reloaddata]。 – palaniraja 2011-12-13 09:44:34

+0

感謝@palaniraja我遇到這個帖子尋找你的解決方案,所以我可以使用表列表來選擇項目。 – robmcm 2012-03-01 13:00:30

13

聲明一個名爲prev一個int變量和實施此方法: -

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

UITableViewCell *cell =[tableView cellForRowAtIndexPath:indexPath]; 

    if (cell.accessoryType==UITableViewCellAccessoryNone) 
    { 
     cell.accessoryType=UITableViewCellAccessoryCheckmark; 
     if (prev!=indexPath.row) { 
     cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prev inSection:0]]; 
     cell.accessoryType=UITableViewCellAccessoryNone; 
     prev=indexPath.row; 
    } 

} 
else{ 
    cell.accessoryType=UITableViewCellAccessoryNone; 
} 
} 
+1

很好的答案,非常整齊。 – AndyDunn 2013-12-06 11:47:55

+0

好的答案,我把它翻譯成下面的Swift。 – 2016-08-26 12:26:12

3

實現在只選擇行對號邏輯的最短和最簡單的方法.....


1. 創建NSIndexPath的全球對象..

selectedIndexPathForCheckMark= [[NSIndexPath alloc] init]; 

2. 在didSelectRowAtIndexPath方法..

// Assiging選擇indexPath到聲明的對象

selectedIndexPathForCheckMark = indexPath; 
[tableView reloadData]; 

3.的cellForRowAtIndexPath ..

if ([selectedIndexPathForCheckMark isEqual:indexPath]) { 
    [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; 
}else { 
    //setAccessoryType None if not get the selected indexPath 
    [cell setAccessoryType:UITableViewCellAccessoryNone]; 
} 
1

以下是我與靜態細胞做,繞過cellForRow

創建一個存儲「選中」單元的位置的變種。

NSInteger _checkedCell; 

然後,只需執行willDisplayCelldidSelectRow方法是這樣的。

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (_checkedCell == indexPath.row) { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } 
    else { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    _checkedCell = indexPath.row; 
    [self.tableView reloadData]; 
} 
1

我知道這個問題是很老,但這裏是一個基於黑莓的反應(我已經被方式進行表決時)雨燕版本

import UIKit 
 

 
class PlacesViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource { 
 

 
    var placesArray = NSMutableArray() 
 
    
 
    var previousCheckedIndex = 0 
 
    
 
    override func viewDidLoad() { 
 
     super.viewDidLoad() 
 

 
     self.placesArray.addObject("Tandil") 
 
     self.placesArray.addObject("Balcarce") 
 
     self.placesArray.addObject("Mar del Plata") 
 
     
 
     self.tableView.rowHeight = UITableViewAutomaticDimension 
 
    } 
 

 
    
 
    
 
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
 
     return self.placesArray.count 
 
    } 
 
    
 
    
 
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
 
     
 
     var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell 
 

 
     cell.textLabel?.text = self.placesArray.objectAtIndex(indexPath.row) as? String 
 
     
 

 
     return cell 
 
    } 
 
    
 
    
 
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
 

 
     if (indexPath.row != previousCheckedIndex) { 
 
      var cell: UITableViewCell = self.tableView.cellForRowAtIndexPath(indexPath)! 
 
      if (cell.accessoryType == UITableViewCellAccessoryType.None) { 
 
       cell.accessoryType = UITableViewCellAccessoryType.Checkmark 
 
       if (previousCheckedIndex != indexPath.row) { 
 
        cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: previousCheckedIndex, inSection: 0))! 
 
        cell.accessoryType = UITableViewCellAccessoryType.None 
 
        previousCheckedIndex = indexPath.row 
 
       } 
 
      } else { 
 
       cell.accessoryType = UITableViewCellAccessoryType.None 
 
      } 
 
     
 
      tableView.reloadData() 
 
     } 
 
    } 
 
}

0

在Swift 2.0使用自定義附件快速查看可視視圖

1º創建Globar var IndexPa日

var indexSelected = NSIndexPath() 

2º在didSelectRowAtIndexPath方法

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     indexSelected = indexPath 
     TB_Lojas.reloadData() 
    } 

3º中的cellForRowAtIndexPath:

if SelectedIndexPath == indexPath { 
       let img = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20)) 
       img.image = UIImage(named: "check") 
       cell.accessoryView = img 
      }else{ 
       let img = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20)) 
       img.image = UIImage(named: "uncheck") 
       cell.accessoryView = img 
      } 
} 
0

考慮到你只想保持一個單一的選擇,如果你有一個自定義UITableViewCell,我會推薦以下內容。

在你UITableViewController

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    //... 
    let data = dataArray[indexPath.row] 
    if data.isSelected { 
     tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None) 
    } 
    //... 

    return cell 
} 

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let data = dataArray[indexPath.row] 
    data.isSelected = true 
    let cell = tableView.cellForRowAtIndexPath(indexPath) 
    cell?.setSelected(true, animated: true) 
} 

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { 
    let data = dataArray[indexPath.row] 
    data.isSelected = false 
    let cell = tableView.cellForRowAtIndexPath(indexPath) 
    cell?.setSelected(false, animated: true) 
} 

在定製UITableViewCell

override func setSelected(selected: Bool, animated: Bool) { 
    super.setSelected(selected, animated: animated) 

    // Configure the view for the selected state 
    self.accessoryType = .None 
    if selected { 
     self.accessoryType = .Checkmark 
    } 
} 

只要未啓用allowsMultipleSelection,它會自動在選擇一個新的處理取消其他細胞。如果啓用了allowMultipleSelection,那麼它也會起作用,除非您只需再次點擊即可取消選擇。

0

BlackBerry的答案在Swift 3. UITableView與標準單元格,選擇0或1個單元格。

private var previousSelection = NSIndexPath() 

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    tableView.deselectRow(at: indexPath, animated: true) 
    let cell = tableView.cellForRow(at: indexPath)! 
    if cell.accessoryType == .none { 
     cell.accessoryType = .checkmark 
     selection = indexPath 

     if previousSelection == IndexPath() { 
      previousSelection = indexPath 
     } else if previousSelection != indexPath { 
      let previousCell = tableView.cellForRow(at: previousSelection) 
      previousCell?.accessoryType = .none 
      previousSelection = indexPath 
     } 
    } else if cell.accessoryType == .checkmark { 
     cell.accessoryType = .none 
     selection = IndexPath() 
    } 

}