swift2 在UITableView中使用UISearchController,并在单元格选择时使用展开序列

g0czyy6m  于 2022-11-06  发布在  Swift
关注(0)|答案(2)|浏览(212)

我有一个UITableViewController,其中有一个单元格可以向下钻取到另一个显示大型数据集的UITableViewController。为了提高可用性,我向视图中添加了一个UISearchController。搜索完成后,用户应单击该单元格,使用展开序列,将用户返回到原始视图控制器,并带回其数据。还有一个嵌入式导航器来帮助导航。
如果我不执行搜索,而只是单击单元格,它会正确地展开并填充原始单元格中的选择,但如果我执行搜索,然后选择一个单元格,则会出现以下错误:

  • popToViewController:转换:当现有的过渡或演示正在发生时被调用;将不会更新导航堆栈。*

下面是我的UISearchController初始化代码:

override func viewDidLoad() {
    super.viewDidLoad()

    // Initialise search controller settings
    searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    searchController.searchBar.sizeToFit()
    searchController.dimsBackgroundDuringPresentation = false
    searchController.delegate = self
    searchController.searchBar.delegate = self
    tableView.tableHeaderView = searchController.searchBar
    definesPresentationContext = true
}

是否有实现此功能的技巧?

  • 谢谢-谢谢
xt0899hw

xt0899hw1#

我在iOS 9.0以后的版本中从searchResultTableView中得到了同样的错误。我在searchResultTableView中调用了unwind segue触发器,但它没有移动到destinationVC,即使我成功地将其数据传递到destinationVC。
我通过创建自定义的展开segue来解决这个问题。
让我们看一下应用程序的结构和逻辑,结构如下所示:
自定义导航控制器(UI导航控制器的子类)-〉主VC-〉推送序列-〉搜索VC(UI搜索控制器的子类)

  1. MainVC嵌入在自定义导航控制器中
    1.如果您从searchResultTableView中选择单元格,则会使用展开序列将应用程序移动到MainVC。我认为您已经在故事板中设置了展开序列。因此,您只需设置要传递到destionationVC的数据,并在此方法中调用performSegueWithIdentifier方法。
// SearchVC or SearchResultVC
-(void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    CustomData *customData = self.searchResults[[self.tableView indexPathForSelectedRow].row];

    self.selectedData = customData;

    [self performSegueWithIdentifier:@"PassResult" sender:nil];

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

 }

1.在SearchVC或SearchResultVC中实现prepareForSegue:sender方法,以便将数据传递到目标VC(MainVC)

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

    if ([segue.identifier isEqualToString:@"PassResult"]) {
        MainVC *destVC = (MainViewController *)segue.destinationViewController;
        destVC.selectedData = self.selectedData;
    }
}

1.使用performSegueWithIdentifier方法调用展开segue时,移动到导航控制器中rootVC有两种方法可以执行此操作请使用展开segue方法或创建自定义segue
展开序列法
如果您连接searchWithResult方法(在MainVC中)以展开序列id PassResult

- (IBAction)searchWithResult:(UIStoryboardSegue *)segue
    {

        [self.navigationController popToRootViewControllerAnimated:YES];

        // Add your code to process your custom data from unwind segue
        ....
    }

自定义序列
创建自定义的segue并实现-perform方法。您可以添加自定义的动画。我只想在这里移动到RootVC。

@implementation CustomUnwindSegue

    - (void)perform
    {

        UIViewController *sourceViewController = (UIViewController *)self.sourceViewController;
        UIViewController *destinationViewController = (UIViewController *)self.destinationViewController;

        [destinationViewController.navigationController popToRootViewControllerAnimated:YES];

    }

    @end

在CustomNavigationController中实现segueForUnwindingToViewController:fromViewController:identifier方法。无法根据推送或模态状态调用此方法,但它在此应用程序结构中有效。

// refer to : http://hmcreation.net/?p=279
    -(UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController
                                     fromViewController:(UIViewController *)fromViewController
                                             identifier:(NSString *)identifier{
        UIStoryboardSegue *segue;

        if ([identifier isEqualToString:@"PassResult"]) {

            segue = [[CustomUnwindSegue alloc]
                                    initWithIdentifier:identifier
                                    source:fromViewController
                                    destination:toViewController];

        }else{

            if ([super respondsToSelector:@selector(unwindForSegue:towardsViewController:)]) {

                NSLog(@"unwinding in iOS9 later");

                [super unwindForSegue:segue towardsViewController:toViewController];

            }

            NSLog(@"segueForUnwinding in iOS9 below");

            segue = [super segueForUnwindingToViewController:toViewController
                                  fromViewController:fromViewController
                                          identifier:identifier];

        }

        return segue;

    }

在iOS9之后,您可以在自定义navigationController中覆盖unwindForSegue:towardsViewController方法。该方法的文档描述了它可以处理弹出的viewController以移动到目标。但它似乎在UISearchController中不起作用。

flvlnr44

flvlnr442#

我也遇到了同样的问题,这里有我的解决方案和解释:当searchController.isActive = true时,它会自行将viewController(包含searchController)推入navigationController。因此,尝试从viewController回溯至initialViewController时,会发生您所描述的错误。若要避免这个问题,您必须先关闭searchController。因此,请改用这一行

performSegue(withIdentifier: "unwindSegueFromViewControllerToInitialViewController", sender: self)

您必须使用此块:

if searchController.isActive {

  searchController.dismiss(animated: false, completion: {
    self.performSegue(withIdentifier: "unwindSegueFromViewControllerToInitialViewController", sender: self)
  })

} else {

  performSegue(withIdentifier: "unwindSegueFromViewControllerToInitialViewController", sender: self)

}

相关问题