6

Mam aplikację z kontrolerem paska tabulacji osadzoną w kontrolerze nawigacyjnym. Aplikacja ma 2 zakładki, pierwsza (wyszukiwanie) ma pasek wyszukiwania zaimplementowany za pomocą kontrolera UISearch. Jeśli mogę przełączyć z tej karty na drugą zakładkę (pliki), a ja szukam, na drugiej karcie dwie rzeczy -Uzyskiwanie czarnego ekranu przy użyciu paska kart podczas wyszukiwania za pomocą narzędzia SearchController

  • Pasek nawigacyjny w drugiej zakładce (pliki do pobrania) znika
  • gdy przyjdę z powrotem do pierwszej zakładki (Search), to pokazuje się czarny ekran

black screen

zrobiłem wszystko to za pomocą serii ujęć.

to moja 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" 
       } 

     } 
    } 


} 

A to moja 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. 
    } 
    */ 


} 

Odpowiedz

8

Wygląda na to, że widok jest dołączony do UISearchController zostanie usunięty z hierarchii widoku. Możesz myśleć o UISearchController jako prezentowanej modalnie, gdy rozpoczynasz wyszukiwanie, a właściwość definesPresentationContext wskazuje, który z nich będzie reprezentował UIViewController (more on this).

Jednym ze sposobów, aby rozwiązać ten problem będzie rekonfiguracji swój storyboard tak, że każda karta ma swój własny UINavigationController (w przypadku, gdy jest to potrzebne dla obu): enter image description here

Zamiast (co podejrzewam masz teraz) : enter image description here

A jeśli chcesz odrzucić UISearchController gdy przełączniki karcie dodać tę funkcję do ViewController:

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

Miałem ten sam problem z kontrolerem nawigacyjnym osadzonym w kontrolerze paska kart. Widok z nawigacją zawiera również pasek wyszukiwania. Nie musiałem niczego zmieniać w scenorysie, ale ustawiłem tylko 'self.definesPresentationContext = true', thanks! – MayaLekova

+0

Ustawienie 'self.definesPresentationContext = true' w viewDidLoad rozwiązało ten problem dla mnie. I mieć oddzielny "UINavigationController" dla każdej karty. – Hendrix