【问题标题】:How to deselect a selected UITableView cell?如何取消选择选定的 UITableView 单元格?
【发布时间】:2011-04-27 10:49:57
【问题描述】:

我正在做一个项目,我必须预先选择一个特定的单元格。

我可以使用-willDisplayCell 预先选择一个单元格,但是当用户单击任何其他单元格时我无法取消选择它。

- (void)tableView:(UITableView*)tableView 
        willDisplayCell:(UITableViewCell*)cell
        forRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    AppDelegate_iPad *appDelegte = 
      (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    if ([appDelegte.indexPathDelegate row] == [indexPath row])
    {
        [cell setSelected:YES];    
    } 
}

- (void)tableView:(UITableView *)tableView 
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    AppDelegate_iPad *appDelegte = 
      (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    NSIndexPath *indexpath1 = appDelegte.indexPathDelegate;
    appDelegte.indexPathDelegate = indexPath;
    [materialTable deselectRowAtIndexPath:indexpath1 animated:NO];
}

你能帮忙吗?

【问题讨论】:

  • 这个问题需要有一个公认的答案

标签: ios objective-c iphone uitableview interface-builder


【解决方案1】:

使用此代码

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
 {
    //Change the selected background view of the cell.
     [tableView deselectRowAtIndexPath:indexPath animated:YES];
 }

斯威夫特 3.0:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //Change the selected background view of the cell.
    tableView.deselectRow(at: indexPath, animated: true)
}

【讨论】:

  • 有一个 didDeselectRowAtIndexPath 用于取消选择前一个。
  • 我认为我不能为这篇文章投票,因为它会导致整数溢出:)
  • 嗨@ram,你需要选择这个问题的答案
  • 我不明白......这段代码永远不会让任何东西被选中。
  • @matrixugly 是对的。在willSelectRowAt: 内执行此操作更合适。在此处查看更完整的答案:stackoverflow.com/questions/12693402/…
【解决方案2】:

在表视图委托的didSelectRowAtIndexpath(或从任何地方)中使用以下方法

[myTable deselectRowAtIndexPath:[myTable indexPathForSelectedRow] animated:YES];

【讨论】:

  • 值得注意的是indexPathForSelectedRow是一个方法而不是一个属性。
  • 甜蜜!不知道[myTable indexPathForSelectedRow]。我之前在循环细胞。谢谢!
  • @FreeAsInBeer 这种区别在某种程度上重要吗?属性访问器是方法。
  • @chaiguy 如果你不介意你的同事考虑你evil,那很好。
  • @Supertecnoboff 两种变体的性能没有差异。
【解决方案3】:

试试这个:

for (NSIndexPath *indexPath in tableView.indexPathsForSelectedRows) {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}

【讨论】:

  • 干得好...我认为第 2 行的“索引”应该是 indexPath
  • iOS 11 Swift 4 不支持此功能
【解决方案4】:

为此在 Swift 中进行扩展可能会很有用。

Swift 4 和 Swift 5:

Swift 扩展(例如在 UITableViewExtension.swift 文件中):

import UIKit

extension UITableView {

    func deselectSelectedRow(animated: Bool)
    {
        if let indexPathForSelectedRow = self.indexPathForSelectedRow {
            self.deselectRow(at: indexPathForSelectedRow, animated: animated)
        }
    }

}

使用例如:

override func viewWillAppear(_ animated: Bool)
{
    super.viewWillAppear(animated)

    self.tableView.deselectSelectedRow(animated: true)
}

【讨论】:

  • 在我看来,这个答案更好,因为将荒凉放在viewWillAppear()方法中有助于用户了解他从哪里回来。
  • 我需要的完美的一个
【解决方案5】:

请检查委托方法是否正确。例如;

-(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

【讨论】:

  • 一直在调用错误的方法,啊!!谢谢!
  • 天啊....该死的自动补全!!!我花了好几个小时才弄明白!!! OMG...我想吻你!
【解决方案6】:

斯威夫特 4:

tableView.deselectRow(at: indexPath, animated: true)

【讨论】:

  • 不需要声明为非可选但这是正确的。
【解决方案7】:

这是 Swift 4 的解决方案

 in tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

只需添加

tableView.deselectRow(at: indexPath, animated: true)

它就像一个魅力

示例:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
//some code
}

【讨论】:

  • 在您在表格视图中添加编辑选择之前,将无法选择任何单元格,因为当您完成选择时它会取消选择它:)
  • 这当然是正确的方法,当你不编辑时,当你“点击一行做某事”时
【解决方案8】:

除了设置单元格被选中,还需要通知tableView单元格被选中。在您的 willDisplayCell: 方法中添加对 -tableView:selectRowAtIndexPath:animated:scrollPosition: 的调用:您将能够正常取消选择它。

- (void)tableView:(UITableView*)tableView 
  willDisplayCell:(UITableViewCell*)cell
forRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    AppDelegate_iPad *appDelegte = (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    if ([appDelegte.indexPathDelegate row] == [indexPath row])
    {
        // SELECT CELL
        [cell setSelected:YES]; 
        // TELL TABLEVIEW THAT ROW IS SELECTED
        [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];   
    } 
}

请务必使用 UITableViewScrollPositionNone 以避免奇怪的滚动行为。

【讨论】:

  • 绝对正确。我认为[cell setSelected:YES] 可以省略:selectRowAtIndexPath 将处理单元格的selected 状态
  • 此答案适用于具有多项选择的 UITableView。竖起大拇指。
【解决方案9】:

基于 saikirans 的解决方案,我写了这个,这对我有帮助。在 .m 文件上:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if(selectedRowIndex && indexPath.row == selectedRowIndex.row) {

        [tableView deselectRowAtIndexPath:indexPath animated:YES];
        selectedRowIndex = nil;

    }

    else {  self.selectedRowIndex = [indexPath retain];   }

    [tableView beginUpdates];
    [tableView endUpdates];

}

在头文件上:

@property (retain, nonatomic) NSIndexPath* selectedRowIndex;

我也不是很有经验,所以请仔细检查内存泄漏等。

【讨论】:

    【解决方案10】:

    这应该可行:

    [tableView deselectRowAtIndexPath:indexpath1 animated:NO];
    

    只要确保 materialTable 和 tableView 指向同一个对象。

    材质是否连接到 Interface Builder 中的 tableView?

    【讨论】:

    • 我已经用 NO 进行了测试,但这也不能解决我的问题。但是我用另一种方式解决了这个问题,即当 didselect 委托触发时重新加载数据。
    【解决方案11】:

    如果您想在第一次单击时选择任何表格单元格并在第二次单击时取消选择,您应该使用以下代码:

    - (void)tableView:(UITableView *)tableView 
            didSelectRowAtIndexPath:(NSIndexPath *)indexPath {   
    
        if (self.selectedIndexPath && 
            [indexPath compare:self.selectedIndexPath] == NSOrderedSame) {
    
            [tableView deselectRowAtIndexPath:indexPath animated:YES];
             self.selectedIndexPath = nil;
        } 
        else {
            self.selectedIndexPath = indexPath;
        }
    }
    

    【讨论】:

      【解决方案12】:

      斯威夫特 4:

      func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
          let cell = tableView.cellForRow(at: indexPath)
          if cell?.isSelected == true { // check if cell has been previously selected
              tableView.deselectRow(at: indexPath, animated: true)
              return nil
          } else {
              return indexPath
          }
      }
      

      【讨论】:

      • 这在 Swift 3 中对我有用。只需要在 tableView.deselectRow... 之后添加 self.tableView(tableView, didDeselectRowAt: indexPath) 因为它不是自动调用的
      【解决方案13】:

      斯威夫特 2.0:

      tableView.deselectRowAtIndexPath(indexPath, animated: true)
      

      【讨论】:

        【解决方案14】:

        斯威夫特 3/4

        在 ViewController 中:

        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            tableView.deselectRow(at: indexPath, animated: true)
        }
        

        在自定义单元格中:

        override func awakeFromNib() {
            super.awakeFromNib()
            selectionStyle = .none
        }
        

        【讨论】:

          【解决方案15】:

          试试这个

          [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
          

          【讨论】:

          • 试着解释你的答案,否则它应该是一个评论。
          【解决方案16】:
          NSIndexPath * index = [self.menuTableView indexPathForSelectedRow];
          [self.menuTableView deselectRowAtIndexPath:index animated:NO];
          

          根据您的代码放置此代码,您将取消选中您的单元格。

          【讨论】:

            【解决方案17】:

            你可以试试这个吗?

            - (void)tableView:(UITableView *)tableView 
              didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
            
                AppDelegate_iPad *appDelegte = 
                (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];
                NSIndexPath *indexpath1 = appDelegte.indexPathDelegate;
                appDelegte.indexPathDelegate = indexPath;
            
                UITableViewCell *prevSelectedCell = [tableView cellForRowAtIndexPath: indexpath1];
                if([prevSelectedCell isSelected]){
                   [prevSelectedCell setSelected:NO];
                }
            }
            

            它对我有用。

            【讨论】:

              【解决方案18】:

              Swift 3.0:

              按照protocol conformance section of the ray wenderlich swift style guide,要将相关方法组合在一起,请将此扩展放在您的视图控制器类下方,如下所示:

              // your view controller
              class MyViewcontroller: UIViewController {
                // class stuff here
              }
              
              // MARK: - UITableViewDelegate
              extension MyViewcontroller: UITableViewDelegate {
                    // use the UITableViewDelegate method tableView(_:didSelectRowAt:)
                  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
              
                      // your code when user select row at indexPath
              
                      // at the end use deselectRow
                      tableView.deselectRow(at: indexPath, animated: true)
                  }
              }
              

              【讨论】:

                【解决方案19】:

                斯威夫特

                func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
                
                    // your code
                
                    // your code
                
                    // and use deselect row to end line of this function
                
                    self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
                
                }
                

                【讨论】:

                  【解决方案20】:
                  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                      tableView.deselectRow(at: indexPath, animated: true)
                  }
                  

                  【讨论】:

                    【解决方案21】:

                    斯威夫特 3

                    我也遇到过这种情况 - 当您导航或放松回到表格视图时,它通常不会为您取消选择之前选择的行。我把这段代码放在表格视图控制器中,效果很好:

                    override func viewDidAppear(_ animated: Bool) {
                        if let lastSelectedRow = tableView.indexPathForSelectedRow {
                            tableView.deselectRow(at: lastSelectedRow, animated: true)
                        }
                    }
                    

                    【讨论】:

                      【解决方案22】:

                      swift 3.0

                          tableView.deselectRow(at: indexPath, animated: true)
                      

                      【讨论】:

                        【解决方案23】:

                        由于预加载数据而在第一次单击时触发取消选择(DidDeselectRowAt);您需要通知 tableView 该行已经被选择开始,以便初始单击然后取消选择该行:

                        //斯威夫特3:

                        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                        
                            if tableView[indexPath.row] == "data value"
                        
                                tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)
                        
                            }
                        }
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2021-08-28
                          • 2014-07-17
                          • 1970-01-01
                          • 2012-03-17
                          • 2021-08-24
                          • 1970-01-01
                          • 1970-01-01
                          • 2011-01-01
                          相关资源
                          最近更新 更多