使用SearchController搜索时使用标签栏获取黑屏

时间:2016-05-20 16:58:19

标签: ios uinavigationcontroller uisearchcontroller nstabviewcontroller

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

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

black screen

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

这是我的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.
    }
    */


}

1 个答案:

答案 0 :(得分:11)

上的JS执行表单

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)。

解决此问题的方法之一是重新配置故事板,以便每个标签都有自己的UINavigationController(以防两者都需要): enter image description here

而不是(我怀疑你现在拥有的): enter image description here

如果您想在标签切换时关闭UISearchController,请将此覆盖添加到ViewController

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