Answers:
在你didSelectRowAtIndexPath
需要调用deselectRowAtIndexPath
取消选择的单元格。
因此,无论您在做什么,didSelectRowAtIndexPath
也都需要调用它deselectRowAtIndexPath
。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Do some stuff when the row is selected
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-deselectRowAtIndexPath:animated:
从中对其tableView属性调用方法-viewDidAppear
。但是,如果你在一个UIViewController子类有一个表视图,你应该叫-deselectRowAtIndexPath:animated:
从-viewDidAppear
自己。:)
-viewWillAppear:
。添加呼叫以[super viewWillAppear:animated]
使其重新工作。
UITableViewController
的clearsSelectionOnViewWillAppear
属性设置为YES
(默认值),并且没有阻止您[super viewWillAppear]
进行调用,则会发生自动取消选择行为。
最干净的方法是在viewWillAppear上:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Unselect the selected row if any
NSIndexPath* selection = [self.tableView indexPathForSelectedRow];
if (selection) {
[self.tableView deselectRowAtIndexPath:selection animated:YES];
}
}
这样,当您返回到控制器时,您将获得淡入选择的动画效果。
取自http://forums.macrumors.com/showthread.php?t=577677
迅捷版
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// deselect the selected row if any
let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
if let selectedRowNotNill = selectedRow {
tableView.deselectRow(at: selectedRowNotNill, animated: true)
}
}
viewDidAppear
。
indexPathForSelectedRow
调用可以返回nil,因此应进行检查。文档状态:标识选定行的行索引和节索引的索引路径;如果索引路径无效,则为nil。
对于Swift用户,请将其添加到您的代码中:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
除了在Swift中而不是在Obj-C中之外,这都是paulthenerd的答案。
使用Swift 4更新
经过几次实验,也基于先前的答案,我得出的结论是,可以通过两种方式实现最佳行为:(实际上几乎是相同的)
// First Solution: delegate of the table View
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
}
// Second Solution: With the life cycle of the view.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
if let selectedRow = selectedRow {
tableView.deselectRow(at: selectedRow, animated: false)
}
}
我个人采用第一个解决方案,因为它更简洁。如果返回tableView时需要一些动画,另一种可能性是使用viewWillAppear
:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let selectedRow: IndexPath? = _view.tableView.indexPathForSelectedRow
if let selectedRow = selectedRow {
_view.tableView.deselectRow(at: selectedRow, animated: true)
}
}
最后但并非最不重要的一点是,如果您使用的是UITableViewController,还可以利用clearsSelectionOnViewWillAppear属性。
要获得Kendall Helmstetter Gelner在其注释中描述的行为,您可能不希望deselectRowAtIndexPath,而是希望控制器上具有clearsSelectionOnViewWillAppear属性。也许是偶然将其设置为“是”?
请参阅默认Apple模板中的注释,以获取新的UITableViewController子类:
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
}
我的向下钻取应用程序也遇到了这个问题。在按下另一个ViewController之后,我将称为VC的viewcontroller返回后,VC中的选定单元格仍然突出显示。在我的应用程序中,我创建了VC以处理向下钻取的第二个级别(三个级别中的第二个级别)。
在我的情况下,问题是VC是UIViewController(包含一个包含TableView的View)。我改用VC作为UITableViewController(包含一个TableView)。从推送返回后,UITableViewController类自动处理表单元格的反突出显示。帖子“ tableView中的deselectRowAtIndexPath问题 ”的第二个答案给出了此问题的更完整答案。
根视图控制器不会发生此问题,因为当我在XCode中将应用程序创建为“基于导航的应用程序”时,生成的根视图控制器已被子类化为UITableViewController。
如果这些都不适合您,请考虑以下解决方法:
使用放松搜索来呼叫:
@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
if let index = tableView.indexPathForSelectedRow {
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
为什么这样 主要是如果您无法在正确的时间运行取消选择代码。我在无法在viewWillAppear上运行时遇到了麻烦,因此展开效果要好得多。
脚步:
将展开的序列(或从上方粘贴)写入您的第一个VC(带表的一个)
转到第二个VC。按住Control并从您用来取消该VC的“取消/完成/其他”按钮中拖动,然后拖动到顶部的“退出”图标。
选择您在步骤1中创建的放松序列
祝好运。
我长期以来一直遇到相同的问题,以防万一其他人正在挣扎:
看看你的 -tableView: cellForRowAtIndexPath:
,看看您是要创建单元格还是使用“重用标识符”。如果是后者,请确保IB中的表具有带有该标识符的单元格。如果您不使用重用标识符,则只需为每行创建一个新单元格。
然后,这将使您的表出现预期的“淡入淡出选定的行”。
对于Swift 3:我希望它可以在viewDidDisappear中使用
定义:
var selectedIndexPath = IndexPath()
在viewDidDisappear中:
override func viewDidDisappear(_ animated: Bool) {
yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}
在didSelectRowAtIndexPath中:-
func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
selectedIndexPath = indexPath
}
如果单元格在触摸后仍保持突出显示,则可以调用UITabelView方法,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
`[tableView deselectRowAtIndexPath:indexPath animated:YES];`
}
或者,您可以使用以下方法并根据需要对其进行修改,
//标记:UITableViewDelegate
func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.backgroundColor = UIColor.greenColor()
}
}
func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.backgroundColor = UIColor.blackColor()
}
}
deselectRowAtIndexPath
如果选择该行将弹出一个新视图,则我更喜欢在viewDidAppear中调用。