UITableViewCell 设置最初选择
Posted
技术标签:
【中文标题】UITableViewCell 设置最初选择【英文标题】:UITableViewCell Set selected initially 【发布时间】:2013-10-10 12:05:15 【问题描述】:您好,我有一种情况,在 iPad 应用程序中,我的 master controller
有列表,详细信息控制器 有它的详细信息,典型的 UISplitViewController
模式。
我想要实现的是,最初应该选择我的第一行,然后我想给用户选择选择。
我正在使用单元格的 setSelected
和 didSelectRowAtIndexPath
方法删除这样的选择。
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSIndexPath* path = [NSIndexPath indexPathForRow:0 inSection:0];
UITableViewCell* cell = [tableView cellForRowAtIndexPath:path];
[cell setSelected:NO];
对于初始单元格,但之后我的无单元格被选中 请帮帮我。
【问题讨论】:
你想自动选择你的tableView的第一行吗? 【参考方案1】:要使单元格显示为选中状态,您必须从 -tableView:willDisplayCell:forRowAtIndexPath:
中调用 -setSelected:animated:
,如下所示:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
if (/* should be selected */)
[cell setSelected:YES animated:NO];
从其他任何地方调用-setSelected
无效。
【讨论】:
如果您可以添加以下行,这个答案会很棒 [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];这是允许用户取消选择单元格。如果缺少此行,则无法取消选择该行。 但是如果你想使用 [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];您必须将其粘贴到 [tableView:cellForRowAtIndexPath:] 中,因为在 [tableView:weillDisplayCell:] 中它将不起作用。 @cateof 的评论应该添加到答案中!非常重要。 这个答案是错误的,因为它只会调用动画块而不会真正将其标记为选中-这会破坏didDeselectRowAt
。使用tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
这个答案有一个问题:如果用户手动取消选择一个预先选择的单元格,然后滚动使单元格不在视图中,最后滚动返回该单元格,则调用tableView(_:willDisplay:forRowAt:)
再次,因为决定是否应该选择它的条件仍然适用,所以重新选择了单元格。【参考方案2】:
试试这个
NSIndexPath* selectedCellIndexPath= [NSIndexPath indexPathForRow:0 inSection:0];
[self tableView:tableViewList didSelectRowAtIndexPath:selectedCellIndexPath];
[tableViewList selectRowAtIndexPath:selectedCellIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
或
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
if (/* should be selected */)
[cell setSelected:YES animated:NO];
Swift 4 版本是
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
func shouldSelect() -> Bool
// Some checks
if shouldSelect()
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
【讨论】:
我使用 willDisplayCell 并按预期工作,谢谢。 如果滚动表格视图,DisplayCell 会出错 您必须考虑到每次显示单元格时都会调用willDisplay
委托函数,如果您最初只想设置一次选择,这可能不是您想要的行为【参考方案3】:
Swift 4:最初选择单元格
import UIKit
class MyViewController: UIViewController, UITableViewDelegate
@IBOutlet weak var tableView: UITableView!
...
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
if /* your code here */ == indexPath.row
tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableView.ScrollPosition.none)
...
【讨论】:
这应该是选定的答案,因为它会在选择另一行时保留选择。也许在 if 语句中添加一个检查,以确保它只选择不是当前的行;你选择了。 我同意道格拉斯的观点。这应该被标记为正确答案。过去几个小时我一直在寻找解决方案,这解决了我的问题。 @user30646 同样在这里!..这应该是正确的答案,因为它也帮助我解决了我的问题! 这往往会起作用,但值得注意的是,它会干扰其他表格视图动画。您的表格视图可能会错误地跳转或滚动。 这是正确的答案。谢谢【参考方案4】:我不知道你期待这个答案。默认情况下,如果您想在不手动选择的情况下选择 tableView 中的第一行,只需像这样启动 didSelectRowAtIndexPath
方法
- (void)viewDidAppear:(BOOL)animated
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:0 inSection:0];
[myTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];
【讨论】:
最好在viewWillAppear
和animated:NO
中执行此操作,以便用户在显示表格视图后看不到被选中的单元格。【参考方案5】:
最佳选择
斯威夫特 5
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
if shouldSelectThisRow
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
else
tableView.deselectRow(at: indexPath, animated: false)
【讨论】:
【参考方案6】:对于 POP 导航也有帮助
.h 文件,
NSIndexPath *defaultSelectedCell
.m 文件
将此代码放入ViewDidLoad
defaultSelectedCell= [NSIndexPath indexPathForRow:0 inSection:0];
在viewDidAppear
[self.tableView selectRowAtIndexPath:defaultSelectedCell animated:NO scrollPosition:UITableViewScrollPositionNone];
这将在您 POP 时有所帮助,将此代码放入 viewWillAppear
[self.catTableView selectRowAtIndexPath:defaultSelectedCell animated:NO scrollPosition:UITableViewScrollPositionNone];
在tableView didSelectRowAtIndexPath
方法中,
defaultSelectedCell = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
无论是第一次加载还是弹出导航,这对我都有帮助。
【讨论】:
【参考方案7】:Swift 4 和 5:最初只选择一次单元格,而 willDisplayCell
不会重置其状态:
override func viewWillAppear(_ animated: Bool)
for section in 0..<tableView.numberOfSections
for row in 0..<tableView.numberOfRows(inSection: section)
let indexPath = IndexPath(row: row, section: section)
if /* your condition for selecting here */
_ = tableView.delegate?.tableView?(tableView, willSelectRowAt: indexPath) // remove if you don't want to inform the delegate
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
tableView.delegate?.tableView?(tableView, didSelectRowAt: indexPath) // remove if you don't want to inform the delegate
【讨论】:
【参考方案8】:Swift 5,非常感谢@Ravindhiran 的回答:
let selectedCellIndexPath = IndexPath(row: 0, section: 0)
tableView(tableViewList, didSelectRowAt: selectedCellIndexPath)
tableViewList.selectRow(at: selectedCellIndexPath, animated: false, scrollPosition: .none)
或
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
if /* should be selected */
cell.setSelected(true, animated: false)
【讨论】:
【参考方案9】:Swift 5.2
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: true)
accessoryType = selected ? .checkmark : .none
backgroundColor = selected ? UIColor.secondarySystemBackground : UIColor.systemBackground
myLabel.textColor = selected ? .tertiaryLabel : .secondaryLabel
self.isUserInteractionEnabled = selected ? false : true
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
let cell = cell as! CustomTableViewCell
if (/* condition is met */)
cell.setSelected(true, animated: true)
【讨论】:
【参考方案10】: func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
// reset cell state
cell.accessoryType = .none // (if you needed)
tableView.deselectRow(at: indexPath, animated: false)
// if need select
cell.accessoryType = .checkmark // (if you needed)
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
// method work fine when tap cell
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
使用 [cell setSelected:YES Animation:NO];单元格点击 didSelectRowAt,didDeselectRowAt 不起作用
【讨论】:
【参考方案11】:我为这个初始选择苦苦挣扎了 5 个多小时。使用 tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
对我有用!
谢谢大家。
【讨论】:
【参考方案12】:我将单元格中的所有选定项目添加到 selectedArray 中。在willDisplay
中,我正在查找 selectedArray 中的当前元素。如果我找到了,那么
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
在我的代码中是这样的:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
let contact = sortedArray[indexPath.section].sectionObjects[indexPath.row]
for selectedContact in selectedContacts
if selectedContact == contact
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
在这种情况下,didSelectRowAt
和 didDeselectRowAt
都可以很好地处理预选的单元格和新选择的单元格,并且在滚动表格时没有问题。
【讨论】:
以上是关于UITableViewCell 设置最初选择的主要内容,如果未能解决你的问题,请参考以下文章
转iOS 通过xib自定义UITableViewCell原创
保存 UITableviewcell accessoryView 的状态