【问题标题】:UITableViewCell Set selected initiallyUITableViewCell 设置最初选择
【发布时间】: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的第一行吗?

标签: ios uitableview uisplitviewcontroller


【解决方案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 都可以很好地处理预选的单元格和新选择的单元格,并且在滚动表格时没有问题。

                【讨论】:

                  猜你喜欢
                  • 2011-08-01
                  • 2011-04-27
                  • 2012-04-11
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-08-21
                  • 2013-08-16
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多