从不活动的 Viewcontroller 推送到新的 Viewcontroller(以编程方式)
Pushing to a new Viewcontroller from an inactive Viewcontroller (programatically)
简短说明。
我有一个 ContainerViewController
正在推送到 navigationStack。
ContainerViewController
有 2 个子视图控制器。一个 SlidePanelViewController
(滑出式菜单)和一个 CenterViewController
(内容)
我的菜单中有一个 "sign Out" 按钮。单击此按钮后,我想将 ContainerViewController
(它是 2 childViewControllers
)推送到我的 LandingPageViewController
.
这是我要调用的函数:
func signOut() {
println("signOut")
// Set up the landing page as the main viewcontroller again.
let mainTableViewController = LandingPageVC()
mainTableViewController.navigationItem.setHidesBackButton(true, animated: false)
mainTableViewController.skipView = false
self.navigationController!.pushViewController(mainTableViewController, animated: true)
// Disable menu access
menuEnabled = false
// change status bar style back to default (black)
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default
}
起初我试着把它放在我的 SlidePanelViewController
里。那没有用。所以我把它放在我假设它属于 ContainerViewController
.
的地方
但是,当我在菜单中单击 signOutButton
时。我遇到了错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
查看错误时。这是导致它的行:
self.navigationController!.pushViewController(mainTableViewController, animated: true)
错误发生后,我通过添加调用该函数的 UINavigationBarButtonItem
(在我的 ContainerViewController
中)来检查该函数是否有效。它完全符合我的要求。
然而,当我从我的菜单中调用这个函数时(同样我的菜单是 ContainerViewController
的 childViewController
)。它不起作用。
我试着这样称呼它:
ContainerViewController().signOut()
我也试过在我的 SidePanelViewController
中添加一个 Delegate
,像这样:
在class之前:
@objc protocol SidePanelViewControllerDelegate {
optional func needsSignOut(sender: SidePanelViewController)
optional func toggleLeftPanel()
optional func collapseSidePanels()
}
在viewDidLoad()
中:
// Make sure your delegate is weak because if a ContainerViewController owns
// a reference to a SidePanelViewController and the container view controller
// is its delegate, you'll end up with a strong reference cycle!
weak var delegate: SidePanelViewControllerDelegate?
在我的点击手势功能中:
func signOutTapGesture() {
println("signOutTapGesture")
selectView(signOutView)
delegate?.needsSignOut?(self)
println(delegate)
}
在我的ContainerViewController
之前class:
var leftViewController: SidePanelViewController?
我的ContainerViewController
class:
class ContainerViewController: UIViewController, CenterViewControllerDelegate, SidePanelViewControllerDelegate, UIGestureRecognizerDelegate {
在我的ContainerViewController's
viewDidLoad()
leftViewController?.delegate = self
然后我将 ContainerViewController
class 中的 signOut
函数更改为:
func needsSignOut(sender: SidePanelViewController) {
println("needsSignOut called")
self.signOut()
}
但是像上面那样使用委托,似乎也没有做任何事情。
任何关于如何从菜单中成功推送我的 LandingPageVC 的帮助将不胜感激! (我没有使用故事板)
问题似乎是 navigationController
为 nil 而您试图强制解包(如您的错误所示)。
我在另一个答案中讨论过的一个问题。
另一个问题可能是您没有添加导航控制器。为此,您需要:
如果您使用的是故事板
您需要确保已嵌入 UINavigationController
。之后,当您使用 navigationController
时,它不会为零,您将能够推送您的视图控制器。
当你在故事板上时:
此外,如果您使用故事板,您是否考虑过使用 segues 来移动而不是调用 presentViewController
?我发现它让一切变得更容易。
如果您没有使用故事板
看看这个post:Programatically creating UINavigationController in iOS
您正试图用 ContainerViewController().signOut()
呼叫 signOut
。这将创建一个新的 ContainerViewController
,因为您还没有将它压入导航控制器的堆栈,所以 navigationController
为零。尝试只调用 self.signOut()
。 (我假设 signOut
的方法是 ContainerViewController
)
更新 - 代表
您的代表 属性 应该进入 SidePanelViewController
。我会给你和如何实现它的例子:
侧面板视图控制器:
(注意 - 协议不必放在此处,但我认为它可以使事情井井有条)
@objc protocol SidePanelViewControllerDelegate {
optional func needsSignOut(sender: SidePanelViewController)
}
class SidePanelViewController: UIViewController {
// Make sure your delegate is weak because if a ContainerViewController owns
// a reference to a SidePanelViewController and the container view controller
// is its delegate, you'll end up with a strong reference cycle!
weak var delegate: SidePanelViewControllerDelegate?
// Called when the UIButton is pressed.
func myButtonWasPressed() {
delegate?.needsSignOut?(self)
}
}
容器视图控制器:
class ContainerViewController: UIViewController {
var sidePanel: SidePanelViewController!
// Setup the side panel...
override func viewDidLoad() {
super.viewDidLoad()
sidePanel.delegate = self
}
func signOut() {
// Sign out stuff here.
}
}
// The ContainerViewController needs to conform to the SidePanelViewControllerDelegate
// protocol if we want the delegate to work. (This could have gone in the initial
// class declaration.)
extension ContainerViewController : SidePanelViewControllerDelegate {
func needsSignOut(sender: SidePanelViewController) {
self.signOut()
}
}
希望对您有所帮助。
简短说明。
我有一个 ContainerViewController
正在推送到 navigationStack。
ContainerViewController
有 2 个子视图控制器。一个 SlidePanelViewController
(滑出式菜单)和一个 CenterViewController
(内容)
我的菜单中有一个 "sign Out" 按钮。单击此按钮后,我想将 ContainerViewController
(它是 2 childViewControllers
)推送到我的 LandingPageViewController
.
这是我要调用的函数:
func signOut() {
println("signOut")
// Set up the landing page as the main viewcontroller again.
let mainTableViewController = LandingPageVC()
mainTableViewController.navigationItem.setHidesBackButton(true, animated: false)
mainTableViewController.skipView = false
self.navigationController!.pushViewController(mainTableViewController, animated: true)
// Disable menu access
menuEnabled = false
// change status bar style back to default (black)
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default
}
起初我试着把它放在我的 SlidePanelViewController
里。那没有用。所以我把它放在我假设它属于 ContainerViewController
.
但是,当我在菜单中单击 signOutButton
时。我遇到了错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
查看错误时。这是导致它的行:
self.navigationController!.pushViewController(mainTableViewController, animated: true)
错误发生后,我通过添加调用该函数的 UINavigationBarButtonItem
(在我的 ContainerViewController
中)来检查该函数是否有效。它完全符合我的要求。
然而,当我从我的菜单中调用这个函数时(同样我的菜单是 ContainerViewController
的 childViewController
)。它不起作用。
我试着这样称呼它:
ContainerViewController().signOut()
我也试过在我的 SidePanelViewController
中添加一个 Delegate
,像这样:
在class之前:
@objc protocol SidePanelViewControllerDelegate {
optional func needsSignOut(sender: SidePanelViewController)
optional func toggleLeftPanel()
optional func collapseSidePanels()
}
在viewDidLoad()
中:
// Make sure your delegate is weak because if a ContainerViewController owns
// a reference to a SidePanelViewController and the container view controller
// is its delegate, you'll end up with a strong reference cycle!
weak var delegate: SidePanelViewControllerDelegate?
在我的点击手势功能中:
func signOutTapGesture() {
println("signOutTapGesture")
selectView(signOutView)
delegate?.needsSignOut?(self)
println(delegate)
}
在我的ContainerViewController
之前class:
var leftViewController: SidePanelViewController?
我的ContainerViewController
class:
class ContainerViewController: UIViewController, CenterViewControllerDelegate, SidePanelViewControllerDelegate, UIGestureRecognizerDelegate {
在我的ContainerViewController's
viewDidLoad()
leftViewController?.delegate = self
然后我将 ContainerViewController
class 中的 signOut
函数更改为:
func needsSignOut(sender: SidePanelViewController) {
println("needsSignOut called")
self.signOut()
}
但是像上面那样使用委托,似乎也没有做任何事情。
任何关于如何从菜单中成功推送我的 LandingPageVC 的帮助将不胜感激! (我没有使用故事板)
问题似乎是 navigationController
为 nil 而您试图强制解包(如您的错误所示)。
我在另一个答案中讨论过的一个问题。
另一个问题可能是您没有添加导航控制器。为此,您需要:
如果您使用的是故事板
您需要确保已嵌入 UINavigationController
。之后,当您使用 navigationController
时,它不会为零,您将能够推送您的视图控制器。
当你在故事板上时:
此外,如果您使用故事板,您是否考虑过使用 segues 来移动而不是调用 presentViewController
?我发现它让一切变得更容易。
如果您没有使用故事板
看看这个post:Programatically creating UINavigationController in iOS
您正试图用 ContainerViewController().signOut()
呼叫 signOut
。这将创建一个新的 ContainerViewController
,因为您还没有将它压入导航控制器的堆栈,所以 navigationController
为零。尝试只调用 self.signOut()
。 (我假设 signOut
的方法是 ContainerViewController
)
更新 - 代表
您的代表 属性 应该进入 SidePanelViewController
。我会给你和如何实现它的例子:
侧面板视图控制器: (注意 - 协议不必放在此处,但我认为它可以使事情井井有条)
@objc protocol SidePanelViewControllerDelegate {
optional func needsSignOut(sender: SidePanelViewController)
}
class SidePanelViewController: UIViewController {
// Make sure your delegate is weak because if a ContainerViewController owns
// a reference to a SidePanelViewController and the container view controller
// is its delegate, you'll end up with a strong reference cycle!
weak var delegate: SidePanelViewControllerDelegate?
// Called when the UIButton is pressed.
func myButtonWasPressed() {
delegate?.needsSignOut?(self)
}
}
容器视图控制器:
class ContainerViewController: UIViewController {
var sidePanel: SidePanelViewController!
// Setup the side panel...
override func viewDidLoad() {
super.viewDidLoad()
sidePanel.delegate = self
}
func signOut() {
// Sign out stuff here.
}
}
// The ContainerViewController needs to conform to the SidePanelViewControllerDelegate
// protocol if we want the delegate to work. (This could have gone in the initial
// class declaration.)
extension ContainerViewController : SidePanelViewControllerDelegate {
func needsSignOut(sender: SidePanelViewController) {
self.signOut()
}
}
希望对您有所帮助。