在使用SearchController进行search时使用标签栏获取黑屏

我有一个embedded在导航控制器中的标签栏控制器的应用程序。 该应用程序有2个选项卡,第一个(search)具有使用UISearchController实现的search栏。 如果我在search时从这个选项卡切换到另一个选项卡(下载),在另一个选项卡上会发生两件事 –

  • 第二个选项卡(下载)中的导航栏消失
  • 当我回到第一个标签(search),它显示一个黑色的屏幕

黑屏

我已经完成了所有这些使用故事板。

这是我的SearchViewController

import UIKit import Alamofire import SwiftyJSON class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating, UISearchBarDelegate{ //MARK: Variables var papers = [Paper]() var filteredPapers = [Paper]() let searchController = UISearchController(searchResultsController: nil) // MARK: Outlets @IBOutlet weak var activityIndicator: UIActivityIndicatorView! @IBOutlet var table: UITableView! @IBOutlet weak var loadingMessageLabel: UILabel! @IBOutlet weak var retryButton: UIButton! //MARK: Actions @IBAction func retryButton(sender: UIButton) { self.loadingMessageLabel.hidden = false self.loadingMessageLabel.text = "While the satellite moves into position..." self.activityIndicator.hidden = false self.activityIndicator.startAnimating() self.retryButton.hidden = true self.getPapersData() } // MARK: Table View func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // If in searching mode, then return the number of results else return the total number // if searchController.active && searchController.searchBar.text != "" { if searchController.active { return filteredPapers.count } return papers.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let paper: Paper // if searchController.active && searchController.searchBar.text != "" { if searchController.active { paper = filteredPapers[indexPath.row] } else { paper = papers[indexPath.row] } if let cell = self.table.dequeueReusableCellWithIdentifier("Cell") as? PapersTableCell { cell.initCell(paper.name, detail: paper.detail) print(cell) return cell } return PapersTableCell() } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { } func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? { let downloadButton = UITableViewRowAction(style: .Normal, title: "Download") { action, index in var url = String(self.papers[indexPath.row].url) url = url.stringByReplacingOccurrencesOfString(" ", withString: "%20") print(url) let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask) // Spinner in cell // var selectCell = self.table.cellForRowAtIndexPath(indexPath) as? PapersTableCell // selectCell!.downloadSpinner.hidden = false // Dismiss the download button self.table.editing = false Alamofire.download(.GET, url, destination: destination).response { _, _, _, error in if let error = error { print("Failed with error: \(error)") } else { print("Downloaded file successfully") } // selectCell?.downloadSpinner.hidden = true } } downloadButton.backgroundColor = UIColor(red:0.30, green:0.85, blue:0.39, alpha:1.0) return [downloadButton] } func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { // the cells you would like the actions to appear needs to be editable return true } func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { // you need to implement this method too or you can't swipe to display the actions } // MARK: Search func filterContentForSearchText(searchText: String, scope: String = "All") { filteredPapers = papers.filter { paper in let categoryMatch = (scope == "All") || (paper.exam == scope) return categoryMatch && paper.name.lowercaseString.containsString(searchText.lowercaseString) } table.reloadData() } func updateSearchResultsForSearchController(searchController: UISearchController) { let searchBar = searchController.searchBar let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex] filterContentForSearchText(searchController.searchBar.text!, scope: scope) } func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) { filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope]) } // MARK: Defaults override func viewDidLoad() { super.viewDidLoad() self.getPapersData() searchController.searchResultsUpdater = self searchController.dimsBackgroundDuringPresentation = false definesPresentationContext = true table.tableHeaderView = searchController.searchBar searchController.searchBar.scopeButtonTitles = ["All", "ST1", "ST2", "PUT", "UT"] searchController.searchBar.delegate = self activityIndicator.startAnimating() } override func viewWillDisappear(animated: Bool) { // if searchController.active { self.searchController.resignFirstResponder() // } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: API call func getPapersData(){ Alamofire.request(.GET, "http://silive.in/bytepad/rest/api/paper/getallpapers?query=") .responseJSON { response in self.activityIndicator.stopAnimating() self.activityIndicator.hidden = true // If the network works fine if response.result.isFailure != true { self.loadingMessageLabel.hidden = true self.table.hidden = false //print(response.result) // result of response serialization let json = JSON(response.result.value!) for item in json { // Split the title on the . to remove the extention let title = item.1["Title"].string!.characters.split(".").map(String.init)[0] let category = item.1["ExamCategory"].string let url = item.1["URL"].string let detail = item.1["PaperCategory"].string let paper = Paper(name: title, exam: category!, url: url!, detail: detail!) self.papers.append(paper) } self.table.reloadData() } // If the network fails else { self.retryButton.hidden = false self.loadingMessageLabel.text = "Check your internet connectivity" } } } } 

这是我的DownloadViewController

 import UIKit import QuickLook class DownloadViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, QLPreviewControllerDataSource { var items = [(name:String, url:String)]() @IBOutlet weak var downloadsTable: UITableView! func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { print(items[indexPath.row].url) // performSegueWithIdentifier("DocumentViewSegue", sender: items[indexPath.row].url) let previewQL = QLPreviewController() // 4 previewQL.dataSource = self // 5 previewQL.currentPreviewItemIndex = indexPath.row // 6 showViewController(previewQL, sender: nil) // 7 } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if let cell = self.downloadsTable.dequeueReusableCellWithIdentifier("Download Cell") as? DownloadsTableCell { cell.initCell(items[indexPath.row].name, detail: "", fileURL: items[indexPath.row].url) return cell } return DownloadsTableCell() } func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { if editingStyle == UITableViewCellEditingStyle.Delete { // let fileManager = NSFileManager.defaultManager() // // // Delete 'hello.swift' file // // do { // try fileManager.removeItemAtPath(String(items[indexPath.row].url)) // } // catch let error as NSError { // print("Ooops! Something went wrong: \(error)") // } items.removeAtIndex(indexPath.row) tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) } } override func viewDidAppear(animated: Bool) { items.removeAll() let documentsUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first! // now lets get the directory contents (including folders) do { let directoryContents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL(documentsUrl, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions()) // print(directoryContents) for var file in directoryContents { print(file.lastPathComponent) print(file.absoluteURL) // Save the data in the list as a tuple self.items.append((file.lastPathComponent!, file.absoluteString)) } } catch let error as NSError { print(error.localizedDescription) } downloadsTable.reloadData() } // MARK: Preview func numberOfPreviewItemsInPreviewController(controller: QLPreviewController) -> Int { return items.count } func previewController(controller: QLPreviewController, previewItemAtIndex index: Int) -> QLPreviewItem { return NSURL(string: items[index].url)! } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func viewWillAppear(animated: Bool) { //do something super.viewWillAppear(true) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { // Get the new view controller using segue.destinationViewController. // Pass the selected object to the new view controller. } */ } 

看起来像您的UISearchController附加到视图从视图层次结构中删除。 您可以将UISearchController视为在您开始search时以模态方式呈现,并且definesPresentationContext属性指示哪个UIViewController将是呈现它的一个( 更多内容 )。

解决这个问题的方法之一就是重新configuration你的故事板,以便每个选项卡都有自己的UINavigationController (万一你需要它们): 在这里输入图像说明

而不是(我怀疑你现在有): 在这里输入图像说明

如果你想在选项卡切换的时候closuresUISearchController ,把这个重载添加到ViewController

 override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) searchController.active = false }