【问题标题】:Select tableview row programmatically以编程方式选择 tableview 行
【发布时间】:2011-01-03 08:26:59
【问题描述】:

如何以编程方式选择UITableView 行,以便

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

被执行? selectRowAtIndexPath 只会突出显示该行。

【问题讨论】:

标签: iphone objective-c cocoa-touch uitableview


【解决方案1】:

就像贾努斯所说的:

调用这个 (-selectRowAtIndexPath:animated:scrollPosition:) 方法 不会导致委托人收到 tableView:willSelectRowAtIndexPath: 或 tableView:didSelectRowAtIndexPath: 消息,也不会发送 UITableViewSelectionDidChangeNotification 通知观察者。

所以你只需要自己调用delegate方法。

例如:

Swift 3 版本:

let indexPath = IndexPath(row: 0, section: 0);
self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)
self.tableView(self.tableView, didSelectRowAt: indexPath)

ObjectiveC 版本:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView selectRowAtIndexPath:indexPath 
                            animated:YES 
                      scrollPosition:UITableViewScrollPositionNone];
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];

Swift 2.3 版本:

 let indexPath = NSIndexPath(forRow: 0, inSection: 0);
 self.tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.None)
 self.tableView(self.tableView, didSelectRowAtIndexPath: indexPath)

【讨论】:

    【解决方案2】:

    来自reference documentation:

    调用此方法不会导致代理收到tableView:willSelectRowAtIndexPath:tableView:didSelectRowAtIndexPath: 消息,也不会向观察者发送UITableViewSelectionDidChangeNotification 通知。

    我会做的是:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        [self doSomethingWithRowAtIndexPath:indexPath];
    }
    

    然后,从您想要调用 selectRowAtIndexPath 的位置,改为调用 doSomethingWithRowAtIndexPath。除此之外,如果您希望 UI 反馈发生,您还可以另外调用 selectRowAtIndexPath。

    【讨论】:

    • 或者当您以编程方式选择行时,您可以自己调用 tableView:didSelectRowAtIndexPath: (在您作为委托连接的类中)。
    • 这种方法对我来说似乎是一种 hack,它确实完成了工作,但我认为应该有更好的方法。
    • 我真的不认为你需要创建一个调用“doSomethingWithRowAtIndexPath”你不能只调用委托方法并传递你需要从你实现的地方执行 didSelect 逻辑的参数委托方法?
    【解决方案3】:

    UITableView 的selectRowAtIndexPath:animated:scrollPosition: 应该可以解决问题。

    只需将 UITableViewScrollPositionNone 传递给 scrollPosition,用户就不会看到任何动作。


    您还应该能够手动运行该操作:

    [theTableView.delegate tableView:theTableView didSelectRowAtIndexPath:indexPath]

    在您selectRowAtIndexPath:animated:scrollPosition: 之后,突出显示以及任何相关逻辑都会发生。

    【讨论】:

    • 对不起,这就是我正在使用的。我不小心放了scrollToRowAtIndexPath。我已经更新了这个问题。 scrollToRowAtIndexPath 仅突出显示单元格。
    • 是的,对不起。它说它不会在我发布的文档链接中触发 didSelectRowAtIndexPath 。我需要学习阅读。
    • @anq:非常感谢!当我在自定义单元格中调用 didSelectRowAtIndexPath:indexPath 时,它对我有帮助。
    【解决方案4】:

    如果您想选择某行,这将对您有所帮助

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [someTableView selectRowAtIndexPath:indexPath 
                               animated:NO 
                         scrollPosition:UITableViewScrollPositionNone];
    

    这也将突出显示该行。 然后委托

     [someTableView.delegate someTableView didSelectRowAtIndexPath:indexPath];
    

    【讨论】:

      【解决方案5】:

      Swift 3/4/5 解决方案

      选择行

      let indexPath = IndexPath(row: 0, section: 0)
      tblView.selectRow(at: indexPath, animated: true, scrollPosition: .bottom)
      myTableView.delegate?.tableView!(myTableView, didSelectRowAt: indexPath)
      

      取消选择行

      let deselectIndexPath = IndexPath(row: 7, section: 0)
      tblView.deselectRow(at: deselectIndexPath, animated: true)
      tblView.delegate?.tableView!(tblView, didDeselectRowAt: indexPath)
      

      【讨论】:

      • 对我来说,添加 '.delegate?'是关键。 (斯威夫特 4.5)
      【解决方案6】:

      iPad 和 iPhone 平台有两种不同的方法,因此您需要同时实现这两种方法:

      • 选择处理程序和
      • 继续。

        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
        
        // Selection handler (for horizontal iPad)
        [self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
        
        // Segue (for iPhone and vertical iPad)
        [self performSegueWithIdentifier:"showDetail" sender:self];
        

      【讨论】:

        【解决方案7】:

        使用此类别选择表格行并在延迟后执行给定的转场。
        在您的 viewDidAppear 方法中调用它:

        [tableViewController delayedSelection:withSegueIdentifier:]
        
        
        @implementation UITableViewController (TLUtils)
        
        -(void)delayedSelection:(NSIndexPath *)idxPath withSegueIdentifier:(NSString *)segueID {
            if (!idxPath) idxPath = [NSIndexPath indexPathForRow:0 inSection:0];                                                                                                                                                                 
            [self performSelector:@selector(selectIndexPath:) withObject:@{@"NSIndexPath": idxPath, @"UIStoryboardSegue": segueID } afterDelay:0];                                                                                               
        }
        
        -(void)selectIndexPath:(NSDictionary *)args {
            NSIndexPath *idxPath = args[@"NSIndexPath"];                                                                                                                                                                                         
            [self.tableView selectRowAtIndexPath:idxPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];                                                                                                                            
        
            if ([self.tableView.delegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)])
                [self.tableView.delegate tableView:self.tableView didSelectRowAtIndexPath:idxPath];                                                                                                                                              
        
            [self performSegueWithIdentifier:args[@"UIStoryboardSegue"] sender:self];                                                                                                                                                            
        }
        
        @end
        

        【讨论】:

        • 这个问题与segues无关。
        • 是的,您的回答中没有任何内容与问题有关
        • 欣赏这个答案。如果用户想要实现相同的行为但正在使用情节提要,这将非常有效。
        猜你喜欢
        • 2016-11-20
        • 2012-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-08
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多