gpt4 book ai didi

ios - 无法呈现 UISearchController

转载 作者:可可西里 更新时间:2023-11-01 01:57:37 24 4
gpt4 key购买 nike

我有以下 View 层次结构:

                         UINavigationController
||
\/
LibraryTableViewController: UITableViewController
||
\/
AlbumsCollectionViewController: UICollectionViewController
||
\/
SongsTableViewController: UITableViewController

我想在 AlbumsCollectionViewController 中有一个搜索栏和一个不同的 SongsTableViewControllernavigationItem.titleView 中显示.

我已经设法在 AlbumsCollectionViewController 中添加了一个有效的搜索栏 |如下:

class AlbumsCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UISearchControllerDelegate, UISearchResultsUpdating, UISearchBarDelegate {

var searchController : UISearchController!

override func viewDidLoad() {
super.viewDidLoad()

initSearchBar()
initNavigationBar()
}

private func initSearchBar() {
self.searchController = UISearchController(searchResultsController: nil)

self.searchController.searchResultsUpdater = self
self.searchController.delegate = self
self.searchController.searchBar.delegate = self

self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.dimsBackgroundDuringPresentation = false

searchController.searchResultsController?.view.isHidden = false
searchController.hidesNavigationBarDuringPresentation = false

self.extendedLayoutIncludesOpaqueBars = true
self.definesPresentationContext = true

searchController.searchBar.backgroundColor = UIColor.black
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes([NSAttributedStringKey.foregroundColor : UIColor.white], for: .normal)

self.navigationItem.titleView = searchController.searchBar

navigationItem.titleView?.isHidden = true
}

private func initNavigationBar() {
searchButton.tintColor = UIColor.white
settingsButton.tintColor = UIColor.white
backButton.tintColor = UIColor.white
self.navigationItem.title = "Artists"
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.white]
}


@IBAction func SearchButtonTapped(_ sender: Any) {
showSearchBar()
}


private func showSearchBar(){
navigationItem.titleView?.isHidden = false
searchController.isActive = true
}
}

请注意,搜索栏隐藏在 ViewDidLoad() 上并在按下按钮时显示,如 SearchButtonTapped 中所示方法。

现在,我正在尝试在 SongsTableViewController 中做同样的事情但是,点击按钮(即调用 SearchButtonTapped )时搜索栏未显示,我收到以下消息:

Warning: Attempt to present <UISearchController: 0x7f8158812b50> on <MyProject.AlbumsCollectionViewController: 0x7f81588023c0> whose view is not in the window hierarchy!

如果我注释了行 searchController.isActive = true然后会显示搜索栏,但是,即使我点击它也不会激活。

编辑

对不起,如果我没说清楚。我有一个单独的UISearchControllerSongsTableViewController .我的意思是我在两个 Controller 中使用相同的逻辑

另请注意,如果我推送了 SongsTableViewController从导航 Controller (即 View 层次结构只有 2 个 Controller (UINavigationController => SongsTableViewController))搜索栏工作正常

这是SongsTableViewController的大部分代码(省略不相关的东西)

import UIKit
import os.log
import MediaPlayer

class SongsTableViewController: UITableViewController, UISearchControllerDelegate, UISearchResultsUpdating, UISearchBarDelegate ,PlayerDelegate, NowPlayingDelegate, SongCellDelegate, SongsOptionsDelegate {

// MARK: properties

var playerManager: PlayerManager? = nil
var dataManager: DataManager? = nil

var tabVC: TabBarController?
var selectedSong: Song?

lazy var optionsTransitionDelegate = PresentationManager()
lazy var playlistTransitionDelegate = PresentationManager()

var searchController : UISearchController!

@IBOutlet var backgroundView: UIView!
@IBOutlet weak var searchButton: UIBarButtonItem!
@IBOutlet weak var settingsButton: UIBarButtonItem!

var albumID: String?
var artistID: String?
var playlist: Playlist?

var songs = [Song]()
var songIndexMap = [String: Int]()
var filteredSongs = [Song]()


override func viewDidLoad() {
super.viewDidLoad()
self.dataManager = DataManager.getInstance()
self.playerManager = PlayerManager.getInstance()

playlistTransitionDelegate.screenRatio = 2.0 / 3.0

if(self.albumID != nil) {
self.songs = SQLiteManager.getAlbumSongs(albumID: self.albumID!)
} else if(self.artistID != nil) {
self.songs = SQLiteManager.getArtistSongs(artistID: self.artistID!)
} else if (self.playlist != nil) {
self.songs = SQLiteManager.getPlaylistSongs(playlist: self.playlist!)
} else {
dataManager?.songsTableViewController = self
}

for i in 0..<songs.count {
songIndexMap[songs[i].id] = i
}

initSearchBar()
initNavigationBar()

if(songs.count == 0 && (!fullListOfSongs() || fullListOfSongs() && dataManager?.getFullSongsCount() == 0)){
tableView.backgroundView = backgroundView
}
tableView.tableFooterView = UIView()

tabVC = tabBarController as? TabBarController
tabVC?.nowPlayingViewController?.delegate = self


}



private func shouldAutorotate() -> Bool {
return false
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return Util.SONG_CELL_HEIGHT
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(isFiltering()) {
return self.filteredSongs.count
} else if (fullListOfSongs()) {
return dataManager!.getFullSongsCount()
}
return self.songs.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "SongTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? SongCell else {
fatalError("The dequeued cell is not an instance of SongCell.")
}
var song: Song?
if(fullListOfSongs()) {
if(isFiltering()){
song = self.filteredSongs[indexPath.row]
} else {
song = dataManager?.getSong(index: indexPath.row)
}
} else {
if(isFiltering()){
song = self.filteredSongs[indexPath.row]
} else {
song = self.songs[indexPath.row]
}
}

cell.setAttributes(song: song!)
cell.delegate = self

cell.preservesSuperviewLayoutMargins = false
return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
self.tableView.deselectRow(at: indexPath, animated: false)
}



// MARK: - Search Bar

func updateSearchResults(for searchController: UISearchController) {
if (!searchController.isActive) {
hideSearchBar()
tableView.reloadData()
}

if(isSearchBarEmpty()) {
return
}

filterSongs(filter: searchController.searchBar.text!)
tableView.reloadData()
}

private func filterSongs(filter: String) {
if(self.albumID != nil) {
self.filteredSongs = SQLiteManager.getAlbumSongs(albumID: self.albumID!, filter: filter)
} else if(self.artistID != nil) {
self.filteredSongs = SQLiteManager.getArtistSongs(artistID: self.artistID!, filter: filter)
} else if(self.playlist != nil) {
self.filteredSongs = SQLiteManager.getPlaylistSongs(playlist: self.playlist!, filter: filter)
}else {
self.filteredSongs = SQLiteManager.getSongs(filter: filter)
}
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
tableView.reloadData()
}
}


private func initSearchBar() {
self.searchController = UISearchController(searchResultsController: nil)

self.searchController.searchResultsUpdater = self
self.searchController.delegate = self
self.searchController.searchBar.delegate = self

self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.dimsBackgroundDuringPresentation = false

searchController.searchResultsController?.view.isHidden = false
searchController.hidesNavigationBarDuringPresentation = false

self.extendedLayoutIncludesOpaqueBars = true
self.definesPresentationContext = true

searchController.searchBar.backgroundColor = UIColor.black
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes([NSAttributedStringKey.foregroundColor : UIColor.white], for: .normal)

self.navigationItem.titleView = searchController.searchBar

navigationItem.titleView?.isHidden = true
}


private func initNavigationBar() {
searchButton.tintColor = UIColor.white
if (fullListOfSongs()) {
searchButton.isEnabled = false
dataManager?.buttons.append(searchButton)
}
settingsButton.tintColor = UIColor.white
self.navigationItem.title = "Songs"
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.white]
}


@IBAction func SearchButtonTapped(_ sender: Any) {
showSearchBar()
}


private func showSearchBar(){
self.navigationItem.titleView?.isHidden = false
self.searchController.isActive = true

DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
self.searchController.searchBar.becomeFirstResponder()
}

navigationItem.rightBarButtonItems![0].isEnabled = false
navigationItem.rightBarButtonItems![0].image = nil
navigationItem.rightBarButtonItems![1].isEnabled = false
navigationItem.rightBarButtonItems![1].image = nil
}

private func hideSearchBar() {
navigationItem.titleView?.isHidden = true

navigationItem.rightBarButtonItems![0].isEnabled = true
navigationItem.rightBarButtonItems![0].image = UIImage(named: "settings")
navigationItem.rightBarButtonItems![1].isEnabled = true
navigationItem.rightBarButtonItems![1].image = UIImage(named: "search")

}

func isFiltering() -> Bool {
if(searchController == nil){
return false
}
return searchController.isActive && !isSearchBarEmpty()
}

private func isSearchBarEmpty() -> Bool {
return searchController.searchBar.text?.isEmpty ?? true
}

private func fullListOfSongs() -> Bool {
return self.playlist == nil && self.albumID == nil && self.artistID == nil
}

}

最佳答案

这在我测试时有效。我认为问题出在 SongsTableViewController 中:self.definesPresentationContext = false。对于推送的 View Controller ,这应该是 true。 (参见文档 here)

对于 SongsTableViewController(推送 View Controller )添加以下内容:

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.definesPresentationContext = true
}

并将其添加到 AlbumsCollectionViewController(初始 View Controller ):

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.definesPresentationContext = false
}

关于ios - 无法呈现 UISearchController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50451647/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com