2016-09-06 66 views
4

我有一個問題,我目前的配置是:UISearchController - 不與子視圖控制器打得很好

的UITableViewController - >的UINavigationController - >一個視圖控制器換出2個視圖控制器。

每個子視圖控制器都有一個與它們關聯的UISearchController。當UISearchBar激活時,它似乎從未擁有正確的位置。

extension MySearchViewController: UISearchControllerDelegate { 

    func willPresentSearchController(searchController: UISearchController) { 
     var adjustedOrigin = searchController.searchBar.frame.origin 
     //FIXME: There's some odd behavior with embedded child VCs where the status bar adjustments are not taken into consideration 
     adjustedOrigin.y += UIApplication.sharedApplication().statusBarFrame.height 
     searchController.searchBar.frame.origin = adjustedOrigin 
     definesPresentationContext = false 
     navigationController?.definesPresentationContext = true 
     navigationController?.extendedLayoutIncludesOpaqueBars = true 
    } 

    func didPresentSearchController(searchController: UISearchController) { 
     definesPresentationContext = true 

    } 

    func didDismissSearchController(searchController: UISearchController) { 
     var adjustedOrigin = searchController.searchBar.frame.origin 
     //FIXME: There's some odd behavior with embedded child VCs where the status bar adjustments are not taken into consideration 
     adjustedOrigin.y -= UIApplication.sharedApplication().statusBarFrame.height 

     searchController.searchBar.frame.origin = adjustedOrigin 
    } 

} 

你可以在上面看到的我試圖手動校正的UISearchBar,這是迄今爲止不理想的偏移量爲原點進行調整。我試圖從故事板中檢查(在很多領域)下面的顯示,並通過代碼幾乎在層次結構中的任何地方。我似乎無法找到抵消的罪魁禍首。默認情況下,會的UISearchBar所有顯示狀態欄下的方式,例如:

search screen

這是沒有我的手工調整,其仍有點過。

有沒有人有解決方案?


編輯1:

進一步證明,一些在父VC是搞亂的偏移量,的UISearchBar的實際的SuperView由-20呈現時抵消。因此,以下修正問題:

import UIKit 

class MySearchController: UISearchController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     edgesForExtendedLayout = .Top 
     extendedLayoutIncludesOpaqueBars = true 
     automaticallyAdjustsScrollViewInsets = true 

     // Do any additional setup after loading the view. 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    override func viewDidLayoutSubviews() { 
     super.viewDidLayoutSubviews() 
     print(active) 

     if active && searchBar.superview!.frame.origin != CGPoint.zero { 
      searchBar.superview?.frame.origin = CGPoint.zero 
     } 
    } 
} 
+0

您是否檢查過VC的孩子是否有任何奇怪的約束? – brkr

+0

我不確定你的意思。 UISearchController獨立於子VC上的自動佈局約束。唯一會受到影響的是UISearchBar(它在展示模式中注入UISearchController時位於容器中)。 UISearchBar已將適當設置的掩碼約束轉換爲不使用指定的基於約束的佈局。 – TheCodingArt

+0

絕大多數情況下,這絕對是溝通東西的東西,無論傳達什麼上下文偏移,我都知道。 – TheCodingArt

回答

0

以下是我發現能可靠地調整狀態欄抵消了搜索控制器被錯誤調整的唯一途徑。

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    //FIXME: Unfortunate hack required to adjust for offset of -20 pulled from ????? where ????? 
    guard let searchBarContainerView = searchBar.superview where (active && searchBarContainerView.frame.origin != CGPoint.zero) else { 
     return 
    } 
    searchBarContainerView.frame.origin = CGPoint.zero 
} 

請注意,物理原點偏移了-20是狀態欄的高度。更正是爲了確保原點被強制設置爲0。

另請注意,這是UISearchController子類中的重寫方法。

-1

爲了將來的參考:通常這種古怪的關鍵是誰在定義表示上下文。

從文檔: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621456-definespresentationcontext

當基於上下文的呈現時,UIKit的開始於所述呈現視圖控制器和走到視圖控制器層次結構。如果它發現視圖控制器的值爲該屬性爲真,它會要求該視圖控制器呈現新視圖控制器。如果沒有視圖控制器定義表示上下文,UIKit會要求窗口的根視圖控制器來處理表示。

所以基本上你必須確保層次結構中正確的視圖控制器將settingPresentationContext設置爲YES。如果放置正確,則不需要偏移或幀修改。在你的情況下,可能是你的父母VC需要定義表示上下文,並確保沒有任何子VC將其設置爲YES。

+0

如果你參考了上面的代碼,那個確切的值已被操縱得太低而沒有成功。我有適當的特殊標誌設置,並做了(回來時,這是作出)操縱它匹配我所期望的沒有成功。所以,除非你有一個適用於這種情況的工作代碼示例,否則這個答案意味着什麼,對發佈文檔之外的問題沒有任何貢獻。 – TheCodingArt

+0

我的感覺是,你誤解了definePresentationContext的用法,因爲你在willPresent上禁用了它,並且啓用了didPresent,恕我直言,這個標誌告訴父/子VC的層次結構中的哪個視圖控制器將負責呈現searchVC它的約束條件適用於將視圖保留在適當位置,因此在搜索欄的演示者上將其設置爲true。根據我自己的經驗,當你必須調整偏移量,框架等......將事物保持就位時,它通常是一種難聞的氣味,這意味着在概念上是錯誤的。希望這可以幫助。 – Emilio

+0

我不會誤解使用情況,但可以。在測試這種情況時,有一個原因讓我們回到這裏。無論如何,這並不能提供解決方案,而只是一種自以爲是的評論。 – TheCodingArt

相關問題