使用 SearchController 搜索时使用标签栏出现黑屏 [英] Getting black screen on using tab bar while searching using SearchController

查看:18
本文介绍了使用 SearchController 搜索时使用标签栏出现黑屏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在导航控制器中嵌入标签栏控制器的应用.该应用程序有 2 个选项卡,第一个(搜索)有一个使用 UISearchController 实现的搜索栏.如果我在搜索时从这个选项卡切换到另一个选项卡(下载),那么会发生两件事 -

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

我已经使用情节提要完成了所有这些工作.

这是我的 SearchViewController

导入 UIKit进口阿拉莫火导入 SwiftyJSON类 ViewController:UIViewController、UITableViewDelegate、UITableViewDataSource、UISearchResultsUpdating、UISearchBarDelegate{//MARK:变量var 论文 = [论文]()var filteredPapers = [论文]()让 searchController = UISearchController(searchResultsController: nil)//MARK:奥特莱斯@IBOutlet 弱 var activityIndi​​cator:UIActivityIndi​​catorView!@IBOutlet var 表:UITableView!@IBOutlet 弱变量 loadingMessageLabel:UILabel!@IBOutlet 弱 var retryButton:UIButton!//MARK:动作@IBAction func retryButton(sender: UIButton) {self.loadingMessageLabel.hidden = falseself.loadingMessageLabel.text = "当卫星移动到位时......"self.activityIndi​​cator.hidden = falseself.activityIndi​​cator.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 = selfactivityIndi​​cator.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.activityIndi​​cator.stopAnimating()self.activityIndi​​cator.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆