当您点击“搜索”(也在导航栏中)时,我正在尝试创建一个显示在导航栏顶部的搜索栏。单击搜索结果将转到详细信息页面,搜索栏将消失。当您单击以返回到主VC时,搜索栏会再次出现。认为这很简单但遇到一些问题。这就是我到目前为止所做的事情
要在HomeVC中点击“搜索”时创建搜索栏,我就这样做了:
@IBAction func SearchAction(sender: AnyObject) {
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
definesPresentationContext = true
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false
self.navigationController?.presentViewController(searchController, animated: true, completion: nil)
}
第1期,当您转到详细信息页面时,搜索栏不会消失。
解决方案:在PrepareForSegue中,我添加了
self.searchController.searchBar.removeFromSuperview()
并将unwindSegue替换为委托,以便当用户从详细信息页面返回到Home VC时,会重新添加搜索栏.HomeVC执行以下操作:
func didDismissDetail() {
self.navigationController?.popViewControllerAnimated(true)
if searchController.active == true {
self.navigationController?.view.addSubview(searchController.searchBar)
}
}
第二期:您搜索的方案中存在错误,点按以转到详细信息页面,返回主页VC,点按取消以关闭搜索控制器。再次单击导航栏中的“搜索”按钮时,没有任何反应。我收到此错误:由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:'应用程序尝试以模态方式呈现活动控制器。 解决方案:我添加了此
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
self.searchController.searchBar.removeFromSuperview()
}
然而,这有效,删除视图时没有动画。对不起,我知道这有点长啰嗦 - 我的问题是:
答案 0 :(得分:3)
您应该使用:
,而不是使用self.searchController.searchBar.removeFromSuperview()
navigationController?.dismissViewControllerAnimated(true, completion: nil)`
解雇视图。此外,您应该为您的segue提供标识符,并在prepareForSegue
中进行检查。您的实现可能如下所示:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ToDetail" {
let destination = segue.destinationViewController as! DetailViewController
navigationController?.dismissViewControllerAnimated(true, completion: nil)
//Pass Info to Detail View
}
}
然后在didSelectRowAtIndexPath
中使用performSegueWithIdentifier
执行您的segue。
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("ToDetail", sender: self)
}
要允许searchBar重新出现,您可以在主视图控制器上设置一个名为searchBarShouldBeOpen
的布尔变量。在SearchAction
函数中将此值设置为true,然后在viewWillAppear
中使用带有searchBarShouldBeOpen
的if语句来决定是否运行SearchAction
。另外,请考虑将SearchAction
作为常规函数,并将示例中显示的最后一行移动到viewDidLoad
。最后,为主视图控制器实现UISearchBarDelegate
并覆盖searchBarCancelButtonClicked
,并在其中将searchBarShouldBeOpen
设置为false。您的主视图控制器看起来像这样:
class ViewController: UIViewController {
//...Your Variables
var searchBarShouldBeOpen: Bool = false
let searchBarKey = "SearchBarText"
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
searchController.searchBar.delegate = self
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Search", style: .Plain, target: self, action: #selector(ViewController.showSearchBar))
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if searchBarShouldBeOpen {
navigationController?.presentViewController(searchController, animated: false, completion: nil)
searchBarShouldBeOpen = true
if let previousText = NSUserDefaults.standardUserDefaults().stringForKey(searchBarKey) {
searchController.searchBar.text = previousText
}
}
}
func showSearchBar() {
navigationController?.presentViewController(searchController, animated: true, completion: nil)
searchBarShouldBeOpen = true
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ToDetail" {
let destination = segue.destinationViewController as! DetailViewController
if searchController.searchBar.text != "" {
NSUserDefaults.standardUserDefaults().setValue(searchController.searchBar.text, forKey: searchBarKey)
}
//Pass Info
}
}
//Your functions...
}
extension ViewController: UISearchBarDelegate {
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchBarShouldBeOpen = false
}
}
在详细信息视图控制器中添加以下内容:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
navigationController?.dismissViewControllerAnimated(true, completion: nil)
}
<强>编辑:强>
更改viewWillAppear
以手动显示UISearchBar
而不使用动画,而不是使用showSearchBar
,以便每次都不会制作动画。
添加了对super.viewWillAppear(animated)
将UISearchBar
的解雇移至详情视图控制器的viewWillAppear
,以便搜索在segue之前不会消失。
使用UISearchBar
(NSUserDefaults
)保留prepareForSegue
的文字,这样就可以将其加载到主广告的viewWillAppear
中查看控制器将搜索设置为以前的搜索。
添加了searchBarKey
常量作为UISearchBar
文本持久性的关键,因此&#34; Magic String&#34;不会用于设置和访问已保存的文本。
注意:您应该考虑使用didSelectRowAtIndexPath
来执行segue。
其他选项:如果您希望UISearchBar
在将主视图控制器转换为详细视图控制器的同时进行动画处理,则可以使用自定义segue(这将使动画有点流畅)。我创建了一个自定义segue示例来创建此效果。请注意,您必须在Interface Builder中更改视图控制器之间的segue以使其具有类型&#34; Custom&#34;并成为UIStoryboardSegue
的以下子类。
class CustomSegue: UIStoryboardSegue {
override func perform() {
let pushOperation = NSBlockOperation()
pushOperation.addExecutionBlock {
self.sourceViewController.navigationController?.pushViewController(self.destinationViewController, animated: true)
}
pushOperation.addExecutionBlock {
self.sourceViewController.navigationController?.dismissViewControllerAnimated(true, completion: nil)
}
pushOperation.queuePriority = .Normal
pushOperation.qualityOfService = .UserInitiated
let operationQueue = NSOperationQueue.mainQueue()
operationQueue.addOperation(pushOperation)
}
}
您可以在以下链接中阅读有关自定义segue中代码的更多信息:
希望这有帮助!如果你需要详细说明,请问! :)
答案 1 :(得分:0)
问题#1,而不是self.searchController.searchBar.removeFromSuperview()
,您可以在self.searchController.isActive = false
中执行prepare(for:sender:)
。当您放松时,这会使搜索栏失效。