I have that error when I want open new view and I don't know what does it mean.
I run that code:
func openMenu(){
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc: UIViewController = storyboard.instantiateViewControllerWithIdentifier("MenuViewController") as UIViewController
self.presentViewController(vc, animated: true, completion: nil)
}
And the error is:
Warning: Attempt to present on whose view is not in the window hierarchy!
I have that Swift code:Swift
And I want execute with Objective-C the Swift code.
Objective-C
replace the line:
self.presentViewController(vc, animated: true, completion: nil)
with:
dispatch_async(dispatch_get_main_queue(), {
self.presentViewController(vc, animated: true, completion: nil)
})
See if it works!
or
why don't you create a segue and call it using:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "Load View") {
// pass data to next view
}
}
Related
I'm learning how to make an app with just a code in Swift. I have encountered this problem:
This is action of a button.
#objc func answerAction() {
let story = UIStoryboard(name: "Main", bundle: nil)
let controller = story.instantiateViewController(withIdentifier: "AccountViewController") as! AccountViewController
self.present(controller, animated: true, completion: nil)
}
If I press it, it shows this error:
Thread 1: "Could not find a storyboard named 'Main' in bundle NSBundle </Users/mas/Library/Developer/CoreSimulator/Devices/A3BEC6D0-3AA6-4193-A755-1181DD580576/data/Containers/Bundle/Application/C80D5D36-EBD8-44D4-AF14-B64E2E7E5587/AppForTest.app> (loaded)"
As I understand, the problem is that I have deleted Main.storyboard and app cannot reach it. So how I should declare in a answerAction story constant?
#objc func answerAction() {
let controller = AccountViewController()
self.present(controller, animated: true, completion: nil)
}
I have the following delegate method that I activate on dismiss of a .formsheet - when it dismisses I need to popToViewController - it appears print("User Logged Out") is also not printing, what is being done incorrectly? I am primarily instructed in how to do this using delegates if possible.
View Controller 2
var delegate: LogoutDelegate?
func logout() {
print("Logout")
self.delegate?.didLogout()
dismiss(animated: true, completion: {
})
}
View Controller 1
protocol LogoutDelegate {
func didLogout() -> Void
}
func didLogout() -> Void {
print("User Logged Out")
self.navigationController?.popToRootViewController(animated: true)
}
Presenting ViewController2:
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Test") as! SettingsViewController
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .formSheet
self.present(navigationController, animated: true, completion: nil)
Assuming your ViewController2 is SettingsViewController, when you are preparing to present ViewController2, you need to set its delegate to your current viewController viewController1.
Sth like this:
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Test") as! SettingsViewController
controller.delegate = self
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .formSheet
self.present(navigationController, animated: true, completion: nil)
Again, I'm assuming this code is in your VC1, so in this case self is your VC1.
This is my Code
#IBAction func backButton(_ sender: UIButton) {
self.dismiss(animated: true, completion: { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
self.present(vc, animated: true, completion: nil)
})
}
this is not working only dissmising
I dont't understand your questions well. I think you want to present a new ViewController. You can use this:
UIView.animate{duration: 0.5, animations: {
(UIApplication.shared.delegate as! AppDelegate).window!.rootViewController = NextViewController()
}}
Problem is that you are dismissing self and then trying to present a new view controller on that exact same self - but at that moment self is already dismissed. You need to present that new view controller from the parent of the current view controller. I believe the best way is to setup a delegate. So the controller that you showed us and that you want to dismiss will have this:
protocol FirstDelegate: class {
func firstDismiss(_ first: First)
}
class First: UIViewController {
weak var delegate: FirstDelegate?
#IBAction func backButton(_ sender: UIButton) {
// this will tell the delegate to dismiss this contorller and present the other one
delegate?.firstDismiss(self)
}
// rest of the code omitted
}
Next, you will have to setup this in the parent that presents First view controller (here I assume that presentFirst method presents the First view controller):
class ParentViewController: UIViewController, FirstDelegate {
// rest of the code
func presentFirst() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let firstVC = storyboard.instantiateViewController(withIdentifier: "First") as! RequestItemPackageDetails
// set delegate to first:
firstVC.delegate = self
self.present(firstVC, animated: true, completion: nil)
}
func firstDismiss(_ first: First) {
first.dismiss(animated: true, completion: { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
self.present(vc, animated: true, completion: nil)
})
}
}
Not quite sure with your Qns, but try this one out.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
vc.previousVC = self
self.present(vc, animated: true)
RequestItemPackageDetails.swift
var previousVC : UIViewController!
override viewDidLoad() {
previousVC.dismiss(animated: false, completion: nil)
}
You can dismiss self and then present another view from rootViewController
self.dismiss(animated: true, completion: { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window!.rootViewController?.present(vc, animated: true, completion: nil)
})
Once a user signs in to my app, I need to take them to a tab view controller so they can use the app to its fullest potential. I have tried to initiate the TabBarController in the buttons onClick function with no success.
PFUser.logInWithUsernameInBackground(username, password:password) {
(user: PFUser?, error: NSError?) -> Void in
if error == nil {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("KlikurHomeTabs") as! UITabBarController
self.presentViewController(vc, animated: true, completion: nil) // this shows it modally
} else if error!.code == 101 {
var invalidLogin:UIAlertView = UIAlertView(title: "Please try again", message: "The username password combo you have us does not match our records, please try again or reset your password.", delegate: self, cancelButtonTitle: "Try again")
invalidLogin.show()
}
}
Can anybody spot what I am doing wrong? I have no clue and have been trying for a while now. Thanks :)
Just change this line and also take out the storyboard line of code
let vc = storyboard.instantiateViewControllerWithIdentifier("KlikurHomeTabs") as! UITabBarController
To
let vc = self.storyboard.instantiateViewControllerWithIdentifier("KlikurHomeTabs")
self.presentViewController(vc!, animated: true, completion: nil)
This is more of an elaboration on Paulw11's comment, but here is what I am doing. I have a "splash" view controller that has 2 storyboard segues, one to a signin/signup view controller, and one to my main tabview controller. Inside viewDidAppear, I check the login status and then perform one of the two segues. Here is an example of the code.
override func viewDidAppear(animated: Bool) {
if needsLogin {
performSegueWithIdentifier("SignIn/SignUP", sender: self)
} else {
performSegueWithIdentifier("MainTabBar", sender: self)
}
}
I'm attempting a simple sign out function where the view returns to my login/sign up view after the user signs out. I have tried using these two methods, but the application crashes every time.
First Method:
#IBAction func signPressed(sender: AnyObject) {
PFUser.logOut()
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("ViewController") as! UIViewController
presentViewController(vc, animated: true, completion: nil)
}
Second Method:
I created the following function:
func loginSetup() {
if (PFUser.currentUser() == nil) {
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
}
}
then added it to my sign out function:
#IBAction func signPressed(sender: AnyObject) {
PFUser.logOut()
self.loginSetup()
}
both crashed and gave me an app delegate error.. whats the issue here?
here is screenshot of error given :
https://40.media.tumblr.com/1f044ecbdd5059836b0a360d16af9846/tumblr_nqzsobll0o1tupbydo1_1280.png
Providing you've set the root VC to the Login/Sign Up screen.
func didTapSignOut(sender: AnyObject)
{
PFUser.logOut()
self.navigationController?.popToRootViewControllerAnimated(true)
}
Then you can call this function in a UIButton IBAction but I call it on my UINavigationBar like so,
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Sign Out", style: .Plain, target: self, action: "didTapSignOut:")