我有一个带有 sideBarMenu 的应用程序,它有五个部分。在我的 Storyboard 中,我创建了嵌入 NavigationController 的启动 MainViewController。然后我创建了相同的五个 VC,并再次将它们嵌入到 NavigationController 中。所以我有 6 个 VC,每个都包装在自己的 NavigationController 中。
每个 VC 都使用具有所选菜单索引的函数实现 sideBarDelegate。
代码如下:
// SideBarTableViewController
protocol SideBarTableViewControllerDelegate {
func SideBarControlDidSelectRow(indexPath: NSIndexPath)
}
class SideBarTableViewController: UITableViewController {
// ...
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
println(indexPath.row)
delegate?.SideBarControlDidSelectRow(indexPath)
}
}
// SideBar class ------------------------------------------------
@objc protocol SideBarDelegate {
func SideBarDidSelectButtonAtIndex(index: Int)
optional func SideBarWillClose()
optional func SideBarWillOpen()
}
class SideBar: NSObject, SideBarTableViewControllerDelegate {
// ...
func SideBarControlDidSelectRow(indexPath: NSIndexPath) {
println(indexPath.row)
delegate!.SideBarDidSelectButtonAtIndex(indexPath.row)
}
}
然后在这个函数中我想呈现所需的 ViewController:
func SideBarDidSelectButtonAtIndex(index: Int) {
presentViewControllerByIndex(index)
}
func presentViewControllerByIndex(index: Int) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
switch index {
case 0:
var viewController = storyBoard.instantiateViewControllerWithIdentifier("SearchVC") as! SearchViewController
viewController.delegate = self
self.presentViewController(viewController, animated: false, completion: nil)
break
// the same code here for other 4 VC's with their StoryboardId's
default: break
}
}
然后在呈现的 View Controller 中,如果用户在菜单中选择另一个部分,我应该在呈现选定的 ViewController 之前销毁此 VC 吗?因为当我运行我的应用程序并开始在 Controller 之间切换时,xCode 中的应用程序内存会增加(screenshot)。
当我看到我开始谷歌搜索并找到 this 时回答。所以我在我的第一个菜单 VC 中创建了一个协议(protocol),只是为了测试。
protocol myProtocol {
func dissmissAndPresend(index: Int) -> Void
}
当我需要展示新的 VC 时,我只需调用:
self.delegate?.dissmissAndPresend(index)
然后在我的 MainVC 中,我实现了这个协议(protocol)并尝试关闭以前的 VC 并呈现新的:
class MainViewController: UIViewController, SideBarDelegate, myProtocol {
func dissmissAndPresend(index: Int) {
self.dismissViewControllerAnimated(false, completion: {
self.presentViewControllerByIndex(index)
})
}
现在,当我启动我的程序并开始单击第一个菜单项时,它会打开新的 VC,但我的内存会像以前一样增加。呈现 View 的 navigationController 也不见了,但在 Storyboard中呈现的 VC 嵌入在 navigationController 中。
我做错了什么?有人可以帮助我吗?
更新::--------------------------------
这是我尝试过的:
class MainViewController: UIViewController, SideBarDelegate, searchVCProtocol {
var searchVC: SearchViewController!
var searchNavController: ShadowUINavigationController!
override func viewDidLoad() {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
searchVC = mainStoryboard.instantiateViewControllerWithIdentifier("SearchVC") as! SearchViewController
searchVC.delegate = self
searchNavController = ShadowUINavigationController(rootViewController: searchVC)
}
func SideBarDidSelectButtonAtIndex(index: Int) {
switch index {
case 0:
println("asda")
self.presentViewController(searchNavController, animated: false, completion: nil)
break
}
}
然后它将用户带到 SearchViewController,如果用户再次打开菜单并再次单击 SearchViewController 会怎样。我怎样才能关闭它并重新打开。这是我尝试过但不起作用的方法:
在 SeachViewController 中我创建了一个协议(protocol):
protocol searchVCProtocol {
func dismissAndPresent(index: Int) -> Void
}
然后我为委托(delegate)添加了一个变量:
var delegate: searchVCProtocol?
然后当用户选择菜单项时它会触发此事件:
func SideBarDidSelectButtonAtIndex(index: Int) {
delegate?.dismissAndPresent(index)
}
在 MainViewController 中,我实现了这个协议(protocol)并创建了 dismissAndPresent 方法,但我不知道如何重新启动呈现的 viewController。
class MainViewController: UIViewController, SideBarDelegate, searchVCProtocol {
func dismissAndPresent(index: Int) {
// code to restart this VC
}
}
我应该编写什么代码来重启呈现的 VC?
最佳答案
您每次都在调用 instantiateViewControllerWithIdentifier,每次都会创建(“实例化”)一个新的 ViewController。最好只执行一次,保留对它的引用,然后根据需要重新使用它。
在这里你可以如何保持引用。首先,您在类级别创建一个新变量:
class MyClass {
var viewController: SearchViewController!
然后,在 viewDidLoad 中,实例化 View Controller 并将其分配给变量。
func viewDidLoad() {
viewController = storyBoard.instantiateViewControllerWithIdentifier("SearchVC") as! SearchViewController
}
viewDidLoad 只被调用一次,因此您不会再创建多个实例。
然后你可以一次又一次地重用这个 View Controller :
func presentViewControllerByIndex(index: Int) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
switch index {
case 0:
// Here you can reuse the formerly created viewcontroller
viewController.delegate = self
self.presentViewController(viewController, animated: false, completion: nil)
break
// the same code here for other 4 VC's with their StoryboardId's
default: break
}
}
关于ios - 呈现新 View Controller 时销毁以前的 View Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31783168/