使用 SearchController 搜索时使用标签栏出现黑屏 [英] Getting black screen on using tab bar while searching using SearchController
问题描述
我有一个在导航控制器中嵌入标签栏控制器的应用.该应用程序有 2 个选项卡,第一个(搜索)有一个使用 UISearchController 实现的搜索栏.如果我在搜索时从这个选项卡切换到另一个选项卡(下载),那么会发生两件事 -
- 第二个标签(下载)中的导航栏消失
- 当我回到第一个选项卡(搜索)时,它显示黑屏
我已经使用情节提要完成了所有这些工作.
这是我的 SearchViewController
导入 UIKit进口阿拉莫火导入 SwiftyJSON类 ViewController:UIViewController、UITableViewDelegate、UITableViewDataSource、UISearchResultsUpdating、UISearchBarDelegate{//MARK:变量var 论文 = [论文]()var filteredPapers = [论文]()让 searchController = UISearchController(searchResultsController: nil)//MARK:奥特莱斯@IBOutlet 弱 var activityIndicator:UIActivityIndicatorView!@IBOutlet var 表:UITableView!@IBOutlet 弱变量 loadingMessageLabel:UILabel!@IBOutlet 弱 var retryButton:UIButton!//MARK:动作@IBAction func retryButton(sender: UIButton) {self.loadingMessageLabel.hidden = falseself.loadingMessageLabel.text = "当卫星移动到位时......"self.activityIndicator.hidden = falseself.activityIndicator.startAnimating()self.retryButton.hidden = trueself.getPapersData()}//MARK: 表格视图func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ->诠释{//如果处于搜索模式,则返回结果个数,否则返回总数//如果 searchController.active &&searchController.searchBar.text != "" {如果 searchController.active {返回filteredPapers.count}返回文件.count}func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->UITableViewCell {让纸:纸//如果 searchController.active &&searchController.searchBar.text != "" {如果 searchController.active {纸=过滤纸[indexPath.row]} 别的 {论文 = 论文[indexPath.row]}如果让 cell = self.table.dequeueReusableCellWithIdentifier("Cell") as?PapersTableCell {cell.initCell(paper.name,详细信息:paper.detail)打印(单元格)返回单元格}返回 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 invar url = String(self.papers[indexPath.row].url)url = url.stringByReplacingOccurrencesOfString(" ", withString: "%20")打印(网址)让目的地 = Alamofire.Request.suggestedDownloadDestination(目录:.DocumentDirectory,域:.UserDomainMask)//单元格中的微调器//var selectCell = self.table.cellForRowAtIndexPath(indexPath) as?论文表细胞//selectCell!.downloadSpinner.hidden = false//关闭下载按钮self.table.editing = falseAlamofire.download(.GET, url, destination: destination).response { _, _, _, 错误如果让错误=错误{print("失败并出现错误:(error)")} 别的 {print("文件下载成功")}//selectCell?.downloadSpinner.hidden = true}}downloadButton.backgroundColor = UIColor(red:0.30, green:0.85, blue:0.39, alpha:1.0)返回 [下载按钮]}func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) ->布尔 {//您希望动作出现的单元格必须是可编辑的返回真}func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {//你也需要实现这个方法,否则你不能滑动显示动作}//标记:搜索func filterContentForSearchText(searchText: String, scope: String = "All") {过滤纸=论文.过滤器{纸在让 categoryMatch = (scope == "All") ||(paper.exam == 范围)返回类别匹配&&paper.name.lowercaseString.containsString(searchText.lowercaseString)}table.reloadData()}func updateSearchResultsForSearchController(searchController: UISearchController) {让 searchBar = searchController.searchBar让范围 = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]filterContentForSearchText(searchController.searchBar.text!,范围:范围)}func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])}//标记:默认值覆盖 func viewDidLoad() {super.viewDidLoad()self.getPapersData()searchController.searchResultsUpdater = 自我searchController.dimsBackgroundDuringPresentation = false定义PresentationContext = truetable.tableHeaderView = searchController.searchBarsearchController.searchBar.scopeButtonTitles = [全部",ST1",ST2",PUT",UT"]searchController.searchBar.delegate = selfactivityIndicator.startAnimating()}覆盖 func viewWillDisappear(动画:布尔){//如果 searchController.active {self.searchController.resignFirstResponder()//}}覆盖 func didReceiveMemoryWarning() {super.didReceiveMemoryWarning()//处理所有可以重新创建的资源.}//MARK: API 调用函数 getPapersData(){Alamofire.request(.GET, "http://silive.in/bytepad/rest/api/paper/getallpapers?query=").responseJSON { 响应self.activityIndicator.stopAnimating()self.activityIndicator.hidden = true//如果网络正常如果 response.result.isFailure != true {self.loadingMessageLabel.hidden = trueself.table.hidden = false//print(response.result)//响应序列化的结果让 json = JSON(response.result.value!)对于 json 中的项目 {//在 .删除扩展让 title = item.1["Title"].string!.characters.split(".").map(String.init)[0]让类别 = item.1["ExamCategory"].string让 url = item.1["URL"].string让 detail = item.1["PaperCategory"].string让论文=论文(名称:标题,考试:类别!,网址:网址!,详细信息:详细信息!)self.papers.append(纸)}self.table.reloadData()}//如果网络失败别的 {self.retryButton.hidden = falseself.loadingMessageLabel.text = "检查您的网络连接"}}}}
这是我的 DownloadViewController
导入 UIKit导入快速查看类下载视图控制器:UIViewController,UITableViewDataSource,UITableViewDelegate,QLPreviewControllerDataSource {var items = [(name:String, url:String)]()@IBOutlet 弱 var downloadsTable:UITableView!func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ->诠释{返回 items.count}func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {打印(项目[indexPath.row].url)//performSegueWithIdentifier("DocumentViewSegue", sender: items[indexPath.row].url)让 previewQL = QLPreviewController()//4previewQL.dataSource = self//5previewQL.currentPreviewItemIndex = indexPath.row//6showViewController(previewQL, sender: nil)//7}func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->UITableViewCell {如果让 cell = self.downloadsTable.dequeueReusableCellWithIdentifier("Download Cell") as?下载表格单元 {cell.initCell(items[indexPath.row].name, detail: "", fileURL: items[indexPath.row].url)返回单元格}返回下载表格单元()}func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {如果editingStyle == UITableViewCellEditingStyle.Delete {//让 fileManager = NSFileManager.defaultManager()//////删除 'hello.swift' 文件//// 做 {//试试 fileManager.removeItemAtPath(String(items[indexPath.row].url))//}//将错误捕获为 NSError {//print("糟糕!出了点问题:(error)")//}items.removeAtIndex(indexPath.row)tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)}}覆盖 func viewDidAppear(动画:布尔){items.removeAll()让documentsUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!//现在让我们获取目录内容(包括文件夹)做 {let directoryContents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL(documentsUrl,包括PropertiesForKeys: nil, options: NSDirectoryEnumerationOptions())//打印(目录内容)对于目录内容中的 var 文件 {打印(file.lastPathComponent)打印(file.absoluteURL)//将列表中的数据保存为元组self.items.append((file.lastPathComponent!, file.absoluteString))}} 将错误捕获为 NSError {打印(错误.localizedDescription)}下载表.reloadData()}//MARK: 预览func numberOfPreviewItemsInPreviewController(控制器:QLPreviewController)->诠释{返回 items.count}func previewController(控制器:QLPreviewController,previewItemAtIndex index:Int)->QLPreviewItem {返回 NSURL(string: items[index].url)!}覆盖 func viewDidLoad() {super.viewDidLoad()//加载视图后做任何额外的设置.}覆盖 func viewWillAppear(动画:布尔){//做一点事super.viewWillAppear(true)}覆盖 func didReceiveMemoryWarning() {super.didReceiveMemoryWarning()//处理所有可以重新创建的资源.}/*//MARK: - 导航//在基于故事板的应用程序中,您通常需要在导航前做一些准备工作覆盖func prepareForSegue(segue:UIStoryboardSegue,发件人:AnyObject?){//使用 segue.destinationViewController 获取新的视图控制器.//将选中的对象传递给新的视图控制器.}*/}
看起来您的 UISearchController
附加到的视图已从视图层次结构中删除.当您开始搜索时,您可以将 UISearchController
视为模态呈现,而 definesPresentationContext
属性指示哪个 UIViewController
将是呈现它的那个(
而不是(我怀疑你现在拥有的):
如果您想在选项卡切换时关闭 UISearchController
,请将此覆盖添加到 ViewController
:
覆盖 func viewWillDisappear(animated: Bool) {super.viewWillDisappear(动画)searchController.active = false}
I have an app with a tab bar controller embedded in a navigation controller. The app has 2 tabs, the first one(search) has a search bar implemented using the UISearchController. If I switch from this tab to the other tab(downloads) while I'm searching, to the other tab two things happen -
- The navigation bar in the second tab(downloads) disappears
- When i come back to the first tab(search), it shows a black screen
I have done all this using the storyboard.
this is my 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"
}
}
}
}
And this is my 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.
}
*/
}
Looks like the view that your UISearchController
is attached to gets removed from the view hierarchy. You can think of the UISearchController
as being presented modally when you start searching, and the definesPresentationContext
property indicates which UIViewController
would be the one to present it (more on this).
One of the ways to fix this would be reconfiguring your storyboard so that each tab has its own UINavigationController
(in case you need it for both):
Instead of (what I suspect you have now):
And if you want to dismiss UISearchController
when the tab switches, add this override to the ViewController
:
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
searchController.active = false
}
这篇关于使用 SearchController 搜索时使用标签栏出现黑屏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!