【发布时间】:2010-12-22 20:58:59
【问题描述】:
什么会导致表格视图单元格在被触摸后保持突出显示?我单击单元格,可以看到它在推送详细视图时保持突出显示。弹出详细视图后,单元格仍会突出显示。
【问题讨论】:
标签: ios uitableview cocoa-touch
什么会导致表格视图单元格在被触摸后保持突出显示?我单击单元格,可以看到它在推送详细视图时保持突出显示。弹出详细视图后,单元格仍会突出显示。
【问题讨论】:
标签: ios uitableview cocoa-touch
在您的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,如果选择该行会打开一个新视图。
-viewDidAppear 调用其tableView 属性上的-deselectRowAtIndexPath:animated: 方法。但是,如果您在 UIViewController 子类中有一个表格视图,您应该自己从-viewDidAppear 调用-deselectRowAtIndexPath:animated:。 :)
-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
Swift 版本
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,因此应该检查它。 The documentation states:标识所选行的行和节索引的索引路径,如果索引路径无效,则为 nil。
对于 Swift 用户,请将其添加到您的代码中:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
这是 paulthenerd 的回答,但在 Swift 而不是 Obj-C 中。
【讨论】:
您是否继承了-(void)viewWillAppear:(BOOL)animated?当您不在自定义方法中调用[super viewWillAppear:animated]; 时,选定的 UITableViewCell 不会取消选择。
【讨论】:
Swift 3 解决方案
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
【讨论】:
如果您使用的是 UITableViewCell,请注释以下行
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
// [super setSelected:selected animated:animated];
}
希望这会有所帮助。
【讨论】:
使用 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 属性。也许这是偶然设置为 YES 的?
查看默认 Apple 模板中新 UITableViewController 子类的注释:
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
}
【讨论】:
Swift 5 解决方案:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
【讨论】:
我的下钻应用程序也遇到了这个问题。在我将调用 VC 的视图控制器在推送另一个视图控制器后返回后,VC 中选定的单元格仍然突出显示。在我的应用程序中,我创建了 VC 来处理我的向下钻取的第二级(三个级别中的)。
我的问题是 VC 是一个 UIViewController(包含一个包含 TableView 的 View)。相反,我使 VC 成为 UITableViewController(包含 TableView)。 UITableViewController 类在从推送返回后自动处理取消突出显示的表格单元格。帖子“Issue with deselectRowAtIndexPath in tableView”的第二个回答对这个问题给出了更完整的答案。
根视图控制器没有出现该问题,因为当我在 XCode 中将应用程序创建为“基于导航的应用程序”时,生成的根视图控制器已经成为 UITableViewController 的子类。
【讨论】:
如果这些都不适合您,请考虑以下解决方法:
使用 unwind segue 调用:
@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
if let index = tableView.indexPathForSelectedRow {
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
为什么要这样做?主要是如果您无法在正确的时间运行取消选择代码。我在 viewWillAppear 上无法正常工作时遇到了麻烦,因此展开效果要好得多。
步骤:
将 unwind segue(或从上方粘贴)写入您的第一个 VC(有表格的那个)
转到第二个 VC。从您用于关闭该 VC 的 Cancel/Done/Etc 按钮按住 Control 并拖动到顶部的退出图标。
选择您在第 1 步中创建的展开转场
祝你好运。
【讨论】:
我正在使用 CoreData,所以对我有用的代码是 Swift 中各种答案的想法的组合:
override func viewDidAppear(_ animated: Bool) {
if let testSelected = yourTable.indexPathForSelectedRow {
yourTable.deselectRow(at: testSelected, animated: true)
}
super.viewDidAppear(true)
}
【讨论】:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
【讨论】:
我已经有同样的问题很长时间了,所以以防万一其他人在苦苦挣扎:
查看您的-tableView: cellForRowAtIndexPath:,看看您是在创建单元格还是在使用“重用标识符”。如果是后者,请确保您在 IB 中的表格有一个带有该标识符的单元格。如果您不使用重用标识符,只需为每一行创建一个新单元格。
这应该会在出现时为您的表格提供预期的“淡入淡出选定行”。
【讨论】:
在 UITableViewCell 类中使用该方法
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
// Just comment This line of code
// [super setSelected:selected animated:animated];
}
【讨论】:
对于 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];`
}
或者,您可以使用以下方法并根据您的要求进行修改,
// MARK: 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()
}
}
【讨论】:
Xcode 10,斯威夫特 4
我遇到了同样的问题,发现我在 tableViewController 的底部留下了一个对 viewWillAppear 的空调用。一旦我删除了空覆盖函数,该行在返回 tableView 视图时不再保持突出显示。
问题函数
override func viewWillAppear(_ animated: Bool) {
// need to remove this function if not being used.
}
删除空函数解决了我的问题。
【讨论】: