I am having problems segueing to my detail view, using Navigation Controller.
I was using a tableview, to display some exercises, and when you clicked the exercise you would seque into the detail view, embedded in nav controller
I have removed the Tableview, and added 3 buttons, each with its' own "show" segue to the detail view. It almost works, but it is now not using my Navigation controller, meaning that the view is just presented kind of like a modal presentation.
I have tried removing the segue on one button and replace with this action:
#IBAction func strengthButton(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destination = storyboard.instantiateViewController(withIdentifier: "ExerciseViewController") as! ExerciseViewController
destination.componentaccessid = -1;
destination.openedFromUrl = false;
destination.exercise = self.strengthexercise
destination.exercisetype = .strength
self.navigationController?.present(destination, animated: true, completion: nil)
}
But that does exactly the same.
I have a prepare function:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier,
let destination = segue.destination as? ExerciseViewController{
destination.componentaccessid = -1;
destination.openedFromUrl = false;
switch identifier{
case "strengthsegue":
destination.exercise = self.strengthexercise
destination.exercisetype = .strength
case "rangesegue":
destination.exercise = self.rangeexercise
destination.exercisetype = .range
case "combinedsegue":
destination.exercise = self.combinedexercise
destination.exercisetype = .combined
default:
print("Nothing")
}
}
}
Try this
self.navigationController?.pushViewController(destination, animated: true)
In your code you are using,
self.navigationController?.present(destination, animated: true, completion: nil)
This will only present the UIViewController.
Instead use,
self.navigationController?.pushViewController(destination, animated: true)
to push the viewController in which the NavigationController is inherited.
Related
I'm using NavigationController to operate the view.
If the value is exceeded on the first view and the value is not satisfied with the 'if' on the second view, I hope 'dismiss' will work.
I have made a similar simple example.
//First View
class ViewController: UIViewController {
#IBAction func goSecond(_ sender: Any) {
let Storyboard = UIStoryboard(name: "Main", bundle: nil)
let DvC = Storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
self.navigationController?.pushViewController(DvC, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
//Second View
class SecondViewController: UIViewController {
#IBAction func goThird(_ sender: Any) {
let Storyboard = UIStoryboard(name: "Main", bundle: nil)
let DvC = Storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
let num = 1
DvC.num = num
self.navigationController?.pushViewController(DvC, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
//Third View
class ThirdViewController: UIViewController {
var num = Int()
override func viewDidLoad() {
super.viewDidLoad()
print("num: ")
print(num)
if(num != 2) {
print("Success")
// dismiss(animated: true, completion: nil)
// navigationController?.dismiss(animated: true, completion: nil)
} else {
print("Failed")
}
}
}
The third view shows "Success", but the codes below it do not work.
dismiss(animated: true, completion: nil) // not work
navigationController?.dismiss(animated: true, completion: nil) // not work
Pressing the button on the first view moves to the second view, and pressing the button on the second view moves to the third view.
If the value passed when I go to the third view is not satisfied with 'if', I want to go back to the first view.
I want the second and third views to end, not just the screen shift.
Like the finish() of Android.
How can I exit the second and third views and return to the first view?
You are pushing the view controllers onto the stack. dismiss is for dismissing VCs presented modally.
What you want to do is pop the VC to go back one.
navigationController?.popViewController(animated: true)
or to go back to the root view.
navigationController?.popToRootViewController(animated: true)
Here i'm dismissing one VC and trying to navigate new VC , but navigation not working. Dismiss VC working fine.
#IBAction func onClickEmailBtn(_ sender: UIButton) {
//dismiss VC
self.dismiss(animated: false, completion: nil)
//Navigate to VC
DispatchQueue.main.async {
let cevc = self.storyboard?.instantiateViewController(withIdentifier: "CEVC") as! EmailViewController
self.navigationController?.pushViewController(cevc, animated: true)
}
}
Here I have one NavigationViewController called VC1, on that I'm presenting one VC called VC2. In this VC2 when I click button I want to navigate new VC called EmailVC.
try this code
#IBAction func onClickEmailBtn(_ sender: UIButton) {
if let controller = self.storyboard?.instantiateViewController(withIdentifier: "CEVC") as! EmailViewController {
self.dismiss(animated: false, completion: nil)
self.presentingViewController?.present(controller, animated: true, completion: nil)
}
}
You were trying to push a ViewVontroller from dismissing view controller,
and the answer which you have accepted is presenting a viewController from dismissing viewController. Although it may serve your purpose, but I am going to answer you original question
// get the object of presenting nanvigation controller(navigation controller with has presented this view controller)
let presentingNavigationController = presentingViewController?.navigationController
dismiss(animated: true) {
let cevc = self.storyboard?.instantiateViewController(withIdentifier: "CEVC") as! EmailViewController
// here you push your view controller with presentingNavigationController
presentingNavigationController?.pushViewController(cevc, animated: true)
}
Try to find out Navigation controller using below code and replace Viewcontroller with your Controller name.
let productVC = SeconViewViewController()
let parentVC = (parent!.presentingViewController as! ViewController).childViewControllers.first as! UINavigationController
self.navigationController?.dismiss(animated: true, completion: {
parentVC.pushViewController(productVC, animated: true)
})
I have read some answers like dismissing the current ViewController but my situation is different because I am presenting another ViewController.
This code presents the view controller with its navigation controller although I cannot access it's properties:
#IBAction func didTouchAddFriend(_ sender: UIButton) {
DispatchQueue.main.async {
let storyBoard = UIStoryboard(name: "CustomContact", bundle: nil)
let customContactVC = storyBoard.instantiateViewController(withIdentifier: "CustomContact")
}
}
While this one doesn't work
#IBAction func didTouchAddFriend(_ sender: UIButton) {
DispatchQueue.main.async {
let navigation = UIStoryboard.init(name: "CustomContact", bundle: nil).instantiateInitialViewController() as! UINavigationController
let pickerUserVC = navigation.viewControllers.first as! CustomContactsViewController
self.present(pickerUserVC, animated: true, completion: nil)
}
}
I have another story board named CustomContact.storyboard which containts a CustomContactsViewController
When I click the didTouchAddFriend, it just shows me this error:
'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <Main.MainViewController: 0x7ff29f06ac00>.'
I cannot understand the error cos when I printed the value of pickerUserVC, it show the right view controller:
<Main.CustomContactsViewController: 0x7fd1b7922400>
MainViewController is the current view controller implementing the didTouchAddFriend function
You ought to present the navigation controller (which hosts the CustomContactsViewController as it's root view controller).
Moreover, you can skip the Dispatch call, since we are in an #IBAction which already runs in the main thread:
#IBAction func didTouchAddFriend(_ sender: UIButton) {
let navigation = UIStoryboard.init(name: "CustomContact", bundle: nil).instantiateInitialViewController() as! UINavigationController
let pickerUserVC = navigation.viewControllers.first as! CustomContactsViewController
self.present(navigation, animated: true, completion: nil)
}
I have a question regarding blureffects on a view controller. I program all of my segues manually for several reasons. But when I go to a viewcontroller that has a blureffect background, I only see a dark gray background. How can I solve this that the view controller blur effect lays on top of another viewcontroller where the content of the previous viewcontroller can be seen through?
The blureffects are now applied by storyboard with transparant background views.
My code for seque is:
Action:
#IBAction func ToUserSections(_ sender: Any) {
let controller =
Navigation.getDestinationViewControllerWith("User",
controllerName: "UserSectionsVC")
present(controller, animated: false, completion: nil)
}
Class:
class Navigation{
static func getDestinationViewControllerWith(_
storyboardName:String, controllerName:String)-> UIViewController{
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
let controller =
storyboard.instantiateViewController(withIdentifier:
controllerName) as UIViewController
return controller
}
}
Hope you can help me with this because it will maximize aesthetics for the app :D
try this.
let viewController : CustomViewControlller = UIStoryboard.getMainStoryboard().instantiateViewController(withIdentifier: "Identifier") as! CustomViewControlller
viewController.modalPresentationStyle = .overCurrentContext
viewController.modalTransitionStyle = .crossDissolve
self.present(viewController, animated: true, completion: { _ in })
Alright for others to know, what worked for me was the following:
At IBAction: adding the following line before presenting
controller.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
Like this:
#IBAction func ToUserSections(_ sender: Any) {
let controller = Navigation.getDestinationViewControllerWith("User", controllerName: "UserSectionsVC")
controller.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
present(controller, animated: false, completion: nil)
}
I've got a button on storyboard Alpha that leads to storyboard Beta using the following code:
#IBAction func showBeta(_ sender: Any) {
let storyboard = UIStoryboard(name: "Beta", bundle: nil)
let bvc = storyboard.instantiateViewController(withIdentifier: "BetaViewController") as! BetaViewController
self.present(bvc, animated: true, completion: nil)
}
This works without any problems.
However, I ran into the issue of not having a back button in Beta because self.present makes the new view appear modally.
I then read this post where the poster had the same problem as me. The answer suggested this code:
self.navigationController?.pushViewController(viewController: UIViewController, animated: Bool)
So I changed my code to:
#IBAction func showBeta(_ sender: Any) {
let storyboard = UIStoryboard(name: "Beta", bundle: nil)
let bvc = storyboard.instantiateViewController(withIdentifier: "BetaViewController") as! BetaViewController
self.navigationController?.pushViewController(bvc, animated: true)
}
However, now nothing happens at all when clicking the button. No errors, nothing. What's going on here?
It seems your AlphaViewController isn't embedded in a UINavigationController.
Try this piece of code:
#IBAction func showBeta(_ sender: Any) {
let storyboard = UIStoryboard(name: "Beta", bundle: nil)
let bvc = storyboard.instantiateViewController(withIdentifier: "BetaViewController") as! BetaViewController
show(bvc, sender: self)
}
This will cause your BetaViewController appear modally if your AlphaViewController isn't embedded in navigation controller and you won't get the back button. But if your AlphaViewController is embedded in navigation controller then your BetaViewController will be shown as left-to-right transition and you will get your desired back button.
To add navigation controller:
If you added your AlphaViewController from interface builder, follow this to embed it in a navigation controller: SelectAlphaViewController -> Editor -> Embed In -> Navigation Controller
Or, if you added your controller programmatically, you can check this answer.