Manually call didSelectRowatIndexPath

前端 未结 5 1329

I am trying to call didSelectRowAtIndexPath programmatically but am having trouble.

[self tableView:playListTbl didSelectRowAtIndexPath:indexPath];
         


        
相关标签:
5条回答
  • 2020-12-14 17:12

    You need to pass a valid argument, if you haven't declared indexPath in the calling scope then you'll get that error. Try:

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:ROW_YOU_WANT_TO_SELECT inSection:SECTION_YOU_WANT_TO_SELECT]
    [self tableView:playListTbl didSelectRowAtIndexPath:indexPath];
    

    Where ROW_YOU_WANT... are to be replaced with the row and section you wish to select.

    However, you really shouldn't ever call this directly. Extract the work being done inside tableView:didSelectRowAtIndexPath: into separate methods and call those directly.

    To address the updated question, you need to use the indexPathsForSelectedRows method on UITableView. Imagine you were populating the table cell text from an array of arrays of strings, something like this:

    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
            UITableViewCell *cell = [tv dequeue...];
            NSArray *rowsForSection = self.sectionsArray[indexPath.section];
            NSString *textForRow = rowsForSection[indexPath.row];
            cell.textLabel.text = textForRow;
            return cell;
        }
    

    Then, to get all the selected text, you'd want to do something like:

    NSArray *selectedIndexPaths = [self.tableView indexPathsForSelectedRows];
    NSMutableArray *selectedTexts = [NSMutableArray array];
    for (NSIndexPath *indexPath in selectedIndexPaths) {
        NSArray *section = self.sectionsArray[indexPath.section];
        NSString *text = section[indexPath.row];
        [selectedTexts addObject:text];
    }
    

    selectedTexts would at that point contain all selected information. Hopefully that example makes sense.

    0 讨论(0)
  • 2020-12-14 17:20

    Starting from Mistalis answer, I made this little ExtendedCell class because I use it in several table views.

    Usage in table view:

    // Here MyTableView is UITableView and UITableViewDelegate
    // but you can separate them.
    
    class MyTableView: UITableView, UITableViewDelegate {
    
        override func dequeueReusableCell(withIdentifier identifier: String) -> UITableViewCell? {
            return MyCell(identifier: identifier, table: self)
        }
    
        // ...
    }
    

    Implementation of your cell:

    class MyCell : ExtendedCell {
    
        convenience init(identifier: String?, table: MyTableView)
        {
            // in this example, MyTableView is both table and delegate
            self.init(identifier: identifier, table: table, delegate: table)
    
            // ...
        }
    
        // At any moment you may call selectTableRow() to select
        // the row associated to this cell.
        func viewItemDetail() {
          selectTableRow()
        }
    }
    

    ExtendedCell class:

    import UIKit
    
    /**
     * UITableViewCell with extended functionality like
     * the ability to trigger a selected row on the table
     */
    class ExtendedCell : UITableViewCell {
    
        // We store the table and delegate to trigger the selected cell
        // See: https://stackoverflow.com/q/18245441/manually-call-did-select-row-at-index-path
    
        weak var table : UITableView!
        weak var delegate : UITableViewDelegate!
    
        convenience init(identifier: String?, table: UITableView, delegate: UITableViewDelegate)
        {
            self.init(style: .default, reuseIdentifier: identifier)
    
            self.table = table
            self.delegate = delegate
        }
    
        func selectTableRow()
        {
            if let indexPath = table.indexPath(for: self) {
                table.selectRow(at: indexPath, animated: true, scrollPosition: .none)
                delegate.tableView!(table, didSelectRowAt: indexPath)
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-14 17:26

    You need to define an indexPath variable if you don't already have one to stick in there.

    Something like:

        NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    
    0 讨论(0)
  • 2020-12-14 17:31

    Just to update @Sourabh's answer, note that you can also provide a scrollPosition when calling selectRow:

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

    Becomes:

    let indexPath = IndexPath(row: 7, section: 0)
    tblView.selectRow(at: indexPath, animated: true, scrollPosition: .top) // <--
    tblView.delegate?.tableView!(tblView, didSelectRowAt: indexPath)
    

    The possible constants are:

    .none

    The table view scrolls the row of interest to be fully visible with a minimum of movement. If the row is already fully visible, no scrolling occurs. For example, if the row is above the visible area, the behavior is identical to that specified by top. This is the default.

    .top

    The table view scrolls the row of interest to the top of the visible table view.

    .middle

    The table view scrolls the row of interest to the middle of the visible table view.

    .bottom

    The table view scrolls the row of interest to the bottom of the visible table view.

    0 讨论(0)
  • 2020-12-14 17:35

    Swift 3.0 Solution

    Manually call didSelectRowAtIndexPath

    let indexPath = IndexPath(row: 7, section: 0)
    tblView.selectRow(at: indexPath, animated: true)
    tblView.delegate?.tableView!(tblView, didSelectRowAt: indexPath)
    
    0 讨论(0)
提交回复
热议问题