[英]Tab Bar and UISearchController giving black screen
我有兩個場景可以通過標簽欄訪問,在場景1有一個搜索欄。 我面臨的問題是,在搜索時是否切換到下載選項卡 -
現在,當我單擊下載選項卡時,導航欄將消失。
這是第一個屏幕的視圖控制器 -
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"
}
}
}
}
我在iOS12中遇到了這個問題,並通過將hostingPresentationContext設置為true來修復它,以便托管搜索控制器的viewcontroller。
self.definesPresentationContext = true
這是因為選項卡可能沒有單獨的導航控制器,可以為您提供黑屏。 為了單獨維護導航層次結構,您應該將uinavigationcontroller嵌入到uiviewcontroller中,並從IB檢查Top Bar作為不透明導航欄而不是Inferred 。 希望這可以幫助。 Cheerio
在幕后,正在呈現搜索控制器。 這是返回時導致黑屏的原因。
最簡單的方法是覆蓋UISearchController並在其viewDidDisappear
設置isActive=false
( https://stackoverflow.com/a/39212080/215748 )。 它有效,但我發現這個解決方案存在一些可用性問題。 我沒有追求它,所以它們可能很容易克服。
在遠離視圖控制器之前調用以下內容:
searchController.dismiss(animated: false, completion: nil)
將其添加到viewDidDisappear
。
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
dismissSearch()
}
func dismissSearch() {
searchController.dismiss(animated: false, completion: nil)
}
不幸的是,切換標簽時不會viewDidDisappear
,因為正在顯示搜索控制器。 它收到了viewDidDisappear
。 要解決這個問題,您可以UITabBarController
並實現UITabBarControllerDelegate
。
// don't forget to set the delegate
extension TabBarController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if let navigationController = viewControllers?[selectedIndex] as? UINavigationController {
for myController in navigationController.viewControllers.flatMap({ $0 as? MyTableViewController }) {
myController.dismissSearch()
}
}
return true
}
看起來您的UISearchController
附加到的視圖將從視圖層次結構中刪除。 您可以將UISearchController
視為在開始搜索時以模態方式呈現,並且definesPresentationContext
屬性指示哪個UIViewController
將是呈現它的人( 更多內容 )。
您可以在可能重復的問題的答案中獲得更多詳細信息: https : //stackoverflow.com/a/37357242/300131
只需將UiNavigationcontroller添加到下載選項卡的uiviewcontroller,它將解決問題停電和隱藏的導航欄
如果你移動這段代碼怎么辦?
self.activityIndicator.stopAnimating()
self.activityIndicator.hidden = true
在你的結果之后? 像這樣:
// If the network works fine
if response.result.isFailure != true {
self.activityIndicator.stopAnimating()
self.activityIndicator.hidden = true
(如果有效,你也需要將它包含在你的另一邊......)
// If the network fails
else {
self.activityIndicator.stopAnimating()
self.activityIndicator.hidden = true
self.retryButton.hidden = false
self.loadingMessageLabel.text = "Check your internet connectivity"
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.