UISearchController' in my UIVIew's
viewDidLoad`を作成するコードがあります。
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.searchBar.delegate = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
controller.hidesNavigationBarDuringPresentation = false //prevent search bar from moving
controller.searchBar.placeholder = "Search for song"
self.myTableView.tableHeaderView = controller.searchBar
return controller
})()
この閉鎖が終了した直後に、コンソールに次の警告が表示されます。
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UISearchController: 0x154d39700>)
私が間違っていることを理解できません。 この同様の質問 は実際には私の状況ではありません(少なくともそうは思わない)。何が起こっている?
UISearchControllerのビューは、割り当てを解除する前にスーパービューから削除する必要があります。 (バグだと思います)
Objective-C ...
-(void)dealloc {
[searchController.view removeFromSuperview]; // It works!
}
スイフト3 ...
deinit {
self.searchController.view.removeFromSuperview()
}
私はこの問題に数週間苦労しました。 ^^
解決しました!簡単な修正でした。このコードを変更しました
class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {
var resultSearchController = UISearchController()
これに:
class ViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {
var resultSearchController: UISearchController!
これにより問題が修正されます。
これが私のために働いたSwiftバージョンです(JJHの回答に似ています):
deinit{
if let superView = resultSearchController.view.superview
{
superView.removeFromSuperview()
}
}
class SampleClass: UITableViewController, UISearchBarDelegate {
private let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.loadViewIfNeeded() // Add this line before accessing searchController
}
}
ViewDidLoad before UISearchControllerを完全に設定するために行を追加することで、いくつかのソリューションを一緒にハックして、機能するようになりました。
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = self.editButtonItem()
if #available(iOS 9.0, *) {
self.resultSearchController.loadViewIfNeeded()// iOS 9
} else {
// Fallback on earlier versions
let _ = self.resultSearchController.view // iOS 8
}
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
self.tableView.reloadData()
}
私のために働いたSwift 2.2バージョン
deinit {
self.searchController?.view.removeFromSuperview()
}
役立つと思います!
Swift2では、明らかなバグが原因で同じエラーメッセージが表示されました。
let alertController = UIAlertController(title: "Oops",
message:"bla.", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Ok",
style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
自分からの愚かなコピーエラーのため、self.presentViewController行を含めていませんでした。これにより、同じエラーが発生しました。
私はこのように働いています
func initSearchControl(){
searchController = UISearchController(searchResultsController: nil)
if #available(iOS 9.0, *) {
searchController.loadViewIfNeeded()
} else {
let _ = self.searchController.view
}
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
searchController.searchBar.sizeToFit()
}
searchController.loadViewIfNeeded()は問題を解決しますが、searchControllerを初期化した後に呼び出す必要があります
viewDidLoad()
で検索コントローラーを作成し、その検索バーをナビゲーションアイテムのタイトルビューとして設定しても、検索コントローラーへの強い参照が作成されないため、割り当てが解除されます。
したがって、これを行う代わりに:
override func viewDidLoad() {
super.viewDidLoad()
// Create search controller
let searchController = UISearchController(searchResultsController: nil)
// Add search bar to navigation bar
navigationItem.titleView = searchController.searchBar
// Size search bar
searchController.searchBar.sizeToFit()
}
これを行う必要があります:
var searchController: UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
// Create search controller
searchController = UISearchController(searchResultsController: nil)
// Add search bar to navigation bar
navigationItem.titleView = searchController.searchBar
// Size search bar
searchController.searchBar.sizeToFit()
}
バグではありません。 ViewControllerを表示せずに作成しないようにする必要があるようです。したがって、SomeViewController()
またはlet variable: SomeViewController
の後に、このself.presentViewController(yourViewController ...etc)
のようなものを呼び出す必要があります。そうしないと、このView Controllerの割り当てが解除されるときにこの警告が表示されます。
Derekの回答を使用しましたが、少し変更する必要がありました。 resultSearchControllerが定義される前にloadViewIfNeeded()の呼び出しが発生したため、提供された回答がクラッシュしました。 (私の宣言は
var resultSearchController: UISearchController!
)。だから私は後でそれを動かしただけでうまくいきました。
呼び出しを完全に省略した場合、バグは残ったため、答えの重要な部分であると確信しています。 iOS 8でテストできませんでした。
ビューが遅延ロードされているように見えます。コントローラーを割り当てて表示しない場合、ビューはロードされません。この場合、コントローラーの割り当てが解除されると、この警告が表示されます。一度表示するか、loadViewIfNeed()メソッドを呼び出すか、 'let _ = controller.view'を使用してビューを強制的にロードし、この警告を回避します。
私はパーティーに少し遅れましたが、ここに私の解決策があります:
var resultSearchController: UISearchController!
override func viewDidLoad()
{
super.viewDidLoad()
self.resultSearchController = ({
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.sizeToFit()
return searchController
})()
self.tableView.tableHeaderView = self.resultSearchController.searchBar
self.tableView.reloadData()
}
私はそれがあなたのために働くことを望みます。