For this problem, the view controller in which this code is run is in the Login.storyboard IB file. The view controller I am trying to present is in the Main.storyboard IB file. The code below is what I'm using to transition from one view controller to another.
func presentNextView() {
let mainSb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let screenAfterLogin: UIViewController = mainSb.instantiateViewControllerWithIdentifier("MainContainerView") as! UIViewController
self.presentViewController(screenAfterLogin, animated: true, completion: nil)
}
Running the application, I set 3 breakpoints on the 3 lines executed in the presentNextView function. Line one is called, line two is called, but line three is NOT called, and the next screen is not presented. Is there something wrong with xCode at the moment?
Checkout the project on github: https://github.com/joshuarcher/RecallBeta
Problem lies in file "HardLoginViewController.swift"
func presentNextView() {
let mainSb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let screenAfterLogin: SecondVC = mainSb.instantiateViewControllerWithIdentifier("SecondVC") as SecondVC
let navigationController = UINavigationController(rootViewController: screenAfterLogin)
presentViewController(navigationController, animated: true, completion: nil)
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
presentNextView()
}
func presentNextView() {
let mainSb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let screenAfterLogin: SecondVC = mainSb.instantiateViewControllerWithIdentifier("SecondVC") as SecondVC
let navigationController = UINavigationController(rootViewController: screenAfterLogin)
presentViewController(navigationController, animated: true, completion: nil)
}
}
import UIKit
class SecondVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.title="Second Screen"
}
}
Related
I have a UIPageController which contains two subviewcontrollers. On start, I'm trying to perform a segue from SubViewControllerOne to LoginViewController when a user isn't authorized. I have a segue in viewDidAppear like so:
performSegue(withIdentifier: "authorizeSegue", sender: self);
This produces an unsuccessful segue and a warning
Warning: Attempt to present <Volley.LoginViewController: 0x7f98bd801e00> on <Volley.SubViewControllerOne: 0x7f98bd608400> whose view is not in the window hierarchy!
I've done this in the past with ViewControllers and TabBarViewControllers successfully.
When I wrap the segue in a timer, or trigger through an IBAction, the segue works perfectly fine. I believe it has something to do with the PageViewController.
class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate {
var subViewControllers = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
self.edgesForExtendedLayout = [];
// Do any additional setup after loading the view.
let subViewControllerOne = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SubViewControllerOne") as! SubViewControllerOne
let subViewControllerTwo = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SubViewControllerTwo") as! SubViewControllerTwo
subViewControllers = [yourPodcastViewController, appearancesViewController]
setViewControllers([subViewControllers[0]], direction: .forward, animated: true, completion: nil)
}
required init?(coder: NSCoder) {
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
}
The navigation controller and PageViewController
The segue from SubViewControllerOne to LoginViewController
I think because of view controller life cycle you should perform segue into viewWillApear
Welp, I've had this issue before when running segues via didSelect on tableviews. The solution is to wrap it in the main thread. Not sure why this is necessary, but it solves my problem.
DispatchQueue.main.async {
self.performSegue(withIdentifier: "authorizeSegue", sender: self);
}
I have two view controller
imag
1.first view controller is main and second is CustomAlertviw controller
main view controller is like above image, when I click continues am showing the customalertview controller, like image. when click the enter pin button I have to dismiss view contoller and show the view controller with uiview on main view controller but tried, it's showing the view controller, there one more custom view is not showing it crashing my app
main view code
#IBAction func backButtonClicked(_ sender: UIButton) {
let myAlert = UIStoryboard(name: "CustomAlertview", bundle: nil).instantiateViewController(withIdentifier: "CustomAlertViewController") as? CustomAlertViewController
myAlert?.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert?.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.present(myAlert!, animated: true, completion: nil)
}
Customalertview controller
#IBAction func enterPinButtonClick(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
let myAlert = UIStoryboard(name: "ScanAndPay", bundle: nil).instantiateViewController(withIdentifier: "ScanAndPayDetailsEntryViewController") as? ScanAndPayDetailsEntryViewController
myAlert?.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert?.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.present(myAlert!, animated: true, completion: nil)
myAlert.valuespass()
}
inside main view controller one function calling from the customalrerview
func valuespass()
{
DispatchQueue.main.async {
self.authType = 1
self.authStatus = false
print("this is calling")
self.pinStatusLabel.text = "Please enter a 4-digit Security PIN"
}
when I am calling this function from the custom alert view application is crashing and showing the hread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value this error. how to can show the all information after dismissing the custom view controller.
You are almost done. present ScanAndPay from FirstView instead of CustomAlertview.
I have done using Delegate as I think it will be fit in this scenario. Follow below steps -
Step 1:
In FirstViewController ,
Add - CustomAlertviewDelegate something like this -
class FirstViewController: UIViewController, CustomAlertviewDelegate {
Now replace your backButtonClicked method -
#IBAction func backButtonClicked(_ sender: UIButton) {
let myAlert = UIStoryboard(name: "CustomAlertview", bundle: nil).instantiateViewController(withIdentifier: "CustomAlertViewController") as? CustomAlertViewController
myAlert?.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert?.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
myAlert.delegate = self
self.present(myAlert!, animated: true, completion: nil)
}
Add a new Delegate method of CustomAlertviewDelegate -
func ScanAndPayView(){
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
let myAlert = UIStoryboard(name: "ScanAndPay", bundle: nil).instantiateViewController(withIdentifier: "ScanAndPayDetailsEntryViewController") as? ScanAndPayDetailsEntryViewController
myAlert?.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert?.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.present(myAlert!, animated: true, completion: nil)
}
}
Step 2:
Now time for CustomAlertview ,
Add protocol for delegate top of the Class -
protocol CustomAlertviewDelegate: class {
func ScanAndPayView()
}
class CustomAlertview: UIViewController{
weak var delegate : CustomAlertviewDelegate!
...
override func viewDidLoad() { // Rest of your code
}
Now time to dismiss current view controller and notify FirstViewController for presenting ScanAndPay view Controller -
#IBAction func enterPinButtonClick(_ sender: Any) {
delegate.ScanAndPayView()
self.dismiss(animated: true, completion: nil)
}
Hope it will help you to achieve what you want.
I have this warning:
Presenting view controllers on detached view controllers is discouraged
I need to know how can set my rootViewController in another VC and avoid this warning
I have this code in my VC:
#IBAction func dissmissInfo(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "firstVC")
present(vc, animated: true, completion: nil)
})
And in the firstVC I have this:
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.keyWindow?.rootViewController = self
}
but when I try to move to another VC I have the same warning:
Presenting view controllers on detached view controllers is discouraged
You mean you want to set firstVC
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "firstVC")
as the new RootViewController?
If YES:
#IBAction func dissmissInfo(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "firstVC")
UIApplication.shared.keyWindow?.rootViewController = vc
})
Then in firstVC, remove
UIApplication.shared.keyWindow?.rootViewController = self
I have some view controllers which are presenting another view controller like so:
class LikeDidTapViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Question") as? QuestionViewController {
if let navigator = navigationController {
navigator.pushViewController(viewController, animated: true)
}
}
}
}
In QuestionViewController I need to check which view controller presented it so I can use conditionals to perform various tasks. How can I accomplish this?
I created a storyboard. The first screen is Launch screen(custom UIViewController called LaunchViewController) and the next screen is custom UITabBarController called SampleTabViewController.
I want to have it automatically go to the SampleTabViewController after 2 seconds on the LaunchViewController.
But some samples that I have found is only from the custom UIViewController to custom UIViewController.
I already set 'sampleTabViewController' on screen associated with "SampleTabViewController" on the storyboard.
Here is my code.
class LaunchViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print("LaunchViewController is initialized");
let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 2 * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
// Put your code which should be executed with a delay here
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("sampleTabViewController")
self.navigationController.pushViewController(controller, animated: true)
}
}
I tried "self.presentViewController(CareGiverViewController(), animated: true, completion: nil)". It works, but the next screen is blank.
I just started learning iOS app with Swift.
Thanks.
Try to set TabbarViewController as rootViewController .
Replace with your push ViewController lines :
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let controller = mainStoryboard.instantiateViewController(withIdentifier: "sampleTabViewController") as! UITabBarController
UIApplication.shared.keyWindow?.rootViewController = controller