UITableViewCell 设置最初选择

Posted

技术标签:

【中文标题】UITableViewCell 设置最初选择【英文标题】:UITableViewCell Set selected initially 【发布时间】:2013-10-10 12:05:15 【问题描述】:

您好,我有一种情况,在 iPad 应用程序中,我的 master controller 有列表,详细信息控制器 有它的详细信息,典型的 UISplitViewController 模式。 我想要实现的是,最初应该选择我的第一行,然后我想给用户选择选择。 我正在使用单元格的 setSelecteddidSelectRowAtIndexPath 方法删除这样的选择。

-(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];

【讨论】:

最好在viewWillAppearanimated: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)
        
    

在这种情况下,didSelectRowAtdidDeselectRowAt 都可以很好地处理预选的单元格和新选择的单元格,并且在滚动表格时没有问题。

【讨论】:

以上是关于UITableViewCell 设置最初选择的主要内容,如果未能解决你的问题,请参考以下文章

转iOS 通过xib自定义UITableViewCell原创

UITableViewCell 选择停留在所有单元格中!

如何强制释放 UITableViewCell

保存 UITableviewcell accessoryView 的状态

dequeueReusableCellWithIdentifier、自定义 UITableViewCell 的问题

从 uitableviewcell 获取文本输入