开发者

How to change clearsSelectionOnViewWillAppear when not using UITableViewController?

I have a UIViewController that manages a UISearchBar and UITab开发者_Go百科leView. I've read that Apple discourage having multiple UIViewControllers manage part of your application, so I did not used UITableViewController to manage the UITableView. Instead, I implemented the UITableViewDelegate and UITableViewDataSource protocol in my own UIViewController.

My question is, since I am no longer using UITableViewController, how do I actually change the clearsSelectionOnViewWillAppear behavior? This property is part of UITableViewController.


Simply by calling

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

in your viewWillAppear: method.


Here the Swift code:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    if let indexPath = tableView.indexPathForSelectedRow() {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }
}


You are most likely overriding the viewWillAppear:animated method and missing the [super viewWillAppear:animated] call.


If you want an interactive animation:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
    if(selectedIndexPath) {
        if(self.transitionCoordinator != nil) {
            [self.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
                [self.tableView deselectRowAtIndexPath:selectedIndexPath animated:YES];
            } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {

            }];

            [self.transitionCoordinator notifyWhenInteractionChangesUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> context) {
                if(context.cancelled) {
                    [self.tableView selectRowAtIndexPath:selectedIndexPath
                                                animated:YES
                                          scrollPosition:UITableViewScrollPositionNone];
                }
            }];
        } else {
            [self.tableView deselectRowAtIndexPath:selectedIndexPath animated:animated];
        }
    }
}

Swift Version:

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

    if let selectedIndexPath = self.tableView.indexPathForSelectedRow {
        if let transitionCoordinator = self.transitionCoordinator {
            transitionCoordinator.animate(alongsideTransition: { (context) in
                self.tableView.deselectRow(at: selectedIndexPath, animated: true)
            }, completion: nil)

            transitionCoordinator.notifyWhenInteractionChanges { (context) in
                if context.isCancelled {
                    self.tableView.selectRow(at: selectedIndexPath, animated: true, scrollPosition: .none)
                }
            }
        } else {
            self.tableView.deselectRow(at: selectedIndexPath, animated: animated)
        }
    }
}

Now you can scrub the animation, i.e. when interactively popping from a navigation controller. It also reselects the row if the interaction was cancelled. This is closer to what is happening inside UITableViewController.


Updated for Swift 5:

override func viewWillAppear(_ animated: Bool) {
        if let indexPath = tableView.indexPathForSelectedRow {
            tableView.deselectRow(at: indexPath, animated: true)
        }
        self.tableView.reloadData()
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜