在呈现新的

时间:2015-08-03 08:52:49

标签: ios swift protocols delegation presentviewcontroller

我有一个sideBarMenu的应用程序,它有五个部分。在我的故事板中,我创建了启动嵌入在NavigationController中的MainViewController。然后我创建了相同的五个VC并再次将它们嵌入到NavigationController中。所以我有6个VC,每个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
    } 
}

然后在呈现的视图控制器中,如果用户选择菜单中的另一个部分,我应该在呈现所选的ViewController之前销毁此VC吗?因为当我运行我的应用程序并开始在控制器之间切换时,xCode中的应用程序内存会增加(screenshot)。

当我看到我开始谷歌搜索并找到this回答。所以我在我的第一个菜单VC中创建了一个用于测试的协议。

protocol myProtocol {
    func dissmissAndPresend(index: Int) -> Void
}

当我需要提出新的VC时,我只需要打电话:

self.delegate?.dissmissAndPresend(index)

然后在我的MainVC中,我实现了这个协议并试图解除之前的VC并提出新的协议:

class MainViewController: UIViewController, SideBarDelegate, myProtocol {

func dissmissAndPresend(index: Int) {
    self.dismissViewControllerAnimated(false, completion: {
        self.presentViewControllerByIndex(index)
    })
}

现在,当我启动程序并开始点击第一个菜单项时,它会打开新VC,但我的内存会像以前一样增加。并且用于呈现视图的navigationController已经消失,但在故事板中呈现的VC嵌入在navigationController中。

我做错了什么?有人能帮助我吗?

UPDATE :: -------------------------------

这是我尝试过的:

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 searchVCProtocol {
    func dismissAndPresent(index: Int) -> Void
}

然后我为委托添加了一个变量:

var delegate: searchVCProtocol?

然后,当用户选择菜单项时,它会触发此事件:

func SideBarDidSelectButtonAtIndex(index: Int) {
    delegate?.dismissAndPresent(index)
}

在MainViewController中,我已经实现了这个协议并创建了dismissAndPresent方法,但我不知道如何重新启动showController。

class MainViewController: UIViewController, SideBarDelegate, searchVCProtocol {
    func dismissAndPresent(index: Int) {
        // code to restart this VC
    }
}

我应该为重启VC提供什么代码?

1 个答案:

答案 0 :(得分:0)

每次调用instantiateViewControllerWithIdentifier时,每次新的ViewController都会创建(“实例化”)。更好的方法是只做一次,保留对它的引用,然后按需重新使用它。

在这里你可以如何保持参考。首先,在类级别创建一个新变量:

class MyClass {
    var viewController: SearchViewController!

然后,在viewDidLoad中,实例化视图控制器并将其分配给变量。

func viewDidLoad() {
    viewController = storyBoard.instantiateViewControllerWithIdentifier("SearchVC") as! SearchViewController
}

viewDidLoad只被调用一次,因此您不再需要创建多个实例。

然后你可以反复重复使用这个viewcontroller:

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
    } 
}