我有一个 UITableViewController ,它有一个向下钻取到显示大型数据集的另一个 UITableViewController 的单元格。为了提高可用性,我在视图中添加了 UISearchController 。搜索完成后,用户应单击该单元格,该单元格使用展开segue将用户返回到原始视图控制器,以恢复其数据。还有一个嵌入式导航器,可以帮助导航。
如果我没有执行搜索并只是单击它正确展开的单元格并填充原始单元格中的选择,但如果我进行搜索然后选择一个单元格,则会出现以下错误:
popToViewController:transition:在发生现有转换或演示时调用;导航堆栈不会更新。
这是我的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
}
是否有实现此功能的技巧?
感谢。
答案 0 :(得分:0)
我在iOS 9.0中的searchResultTableView中遇到了同样的错误。 我在searchResultTableView中调用unwind segue触发器,但它没有移动到destinationVC,即使我已成功将其数据传递到destinationVC。
我通过创建自定义展开segue解决了这个问题。
让我们来看看应用程序结构及其逻辑。结构将如下所示:
CustomNavigationController(UINavigationController的子类) - > MainVC - > push segue - > SearchVC(UISearchController的子类)
如果从searchResultTableView中选择单元格,
应用程序使用unwind segue移动到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];
}
在SearchVC中实现prepareForSegue:sender方法 SearchResultVC用于将数据传递到destinationVC(MainVC)
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:@"PassResult"]) {
MainVC *destVC = (MainViewController *)segue.destinationViewController;
destVC.selectedData = self.selectedData;
}
}
使用performSegueWithIdentifier方法调用unwind segue时,请在导航控制器中移至rootVC。你有两种选择。使用展开segue方法或创建自定义segue。
展开segue方法
如果您连接searchWithResult
方法(在MainVC中)以展开segue标识PassResult
:
- (IBAction)searchWithResult:(UIStoryboardSegue *)segue
{
[self.navigationController popToRootViewControllerAnimated:YES];
// Add your code to process your custom data from unwind segue
....
}
自定义segue
创建自定义segue并实施-perform
方法。您可以添加自定义动画。我只想在这里转移到RootVC。
@implementation CustomUnwindSegue
- (void)perform
{
UIViewController *sourceViewController = (UIViewController *)self.sourceViewController;
UIViewController *destinationViewController = (UIViewController *)self.destinationViewController;
[destinationViewController.navigationController popToRootViewControllerAnimated:YES];
}
@end
实现segueForUnwindingToViewController:fromViewController:CustomNavigationController中的identifier方法。无法根据推送或模态状态调用此方法,但它适用于此app结构。
// 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方法。该方法的文档描述了它可以处理弹出viewControllers以移动到目标。但看起来它在UISearchController中不起作用。
答案 1 :(得分:0)
我遇到了同样的问题,并且有我的解决方案和解释:当searchController.isActive = true时,它会自动将navigationController(包含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)
}