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?
Related
I have a design made in nib and in round about all ViewControllers I am loading that nib design.
Now as that was common footer so I managed to used it in the footer of all other view controllers.
Now what I want : I want that whenever User click on a footer it must start a new View Controller that will show what you can say "About us " view controller.
What I am doing:
// ON CLICK OF FOOTER I AM DOING
let mAboutUs = self.storyboard?.instantiateViewController(withIdentifier: "idAboutUs") as! AboutUs
mAboutUs.modalPresentationStyle = .fullScreen
self.present(mAboutUs, animated: true) {
}
but I am getting following error
Value of type 'FooterView' has no member 'storyboard'
My Understanding: I think from nib file we can not start a new ViewController, But I really do not want to do this thing in all other View controllers in which I added this nib (FooterView) as my footer view at bottom of each view controller.
Please help me!!!!
A UIView subclass doesn't contain a storyboard property it's for a vc subclass , You need
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "idAboutUs") as! AboutUs
if you want to present a vc from inisde the view FooterView then add a delegate like
weak var delegate:VCName?
When you create an instance
let ins = FooterView() // or from storyboard
ins.delegate = self
Then use
delegate?.present(mAboutUs, animated: true)
inside the view's class
You can use a delegate that all vcs conforms to but the easiest is to add this extension
extension UIViewController {
func topMostViewController() -> UIViewController {
if let presented = self.presentedViewController {
return presented.topMostViewController()
}
if let navigation = self as? UINavigationController {
return navigation.visibleViewController?.topMostViewController() ?? navigation
}
if let tab = self as? UITabBarController {
return tab.selectedViewController?.topMostViewController() ?? tab
}
return self
}
}
Then
guard let currentVC = (UIApplication.shared.delegate as! AppDelegate).window?.rootViewController.topMostViewController() else { return }
currentVC.present(mAboutUs, animated: true)
Your code should look similar to this:
let vc = UIStoryboard(name: "<Name of the storyboard that contains the About Us VC>", bundle: nil).instantiateViewController(withIdentifier: "idAboutUs") as! AboutUs
self.present(vc, animated: true) {
}
I want to change the default selected view controller of a UITabBar / UITabBarController via selectedIndex.
I tried other solutions I saw in other threads, like changing it in the AppDelegate or in ViewDidAppear like this:
class MainTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
setupTabBar()
}
override func viewDidAppear(_ animated: Bool) {
// this is the attempt to set the selected index that doesn't work
self.tabBarController?.selectedIndex = 2
}
func setupTabBar(){
let vc1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "mainvc")
let vc2 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "secondvc")
let vc3 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "thirdvc")
let FirstController = UINavigationController(rootViewController: vc1)
let SecondController = UINavigationController(rootViewController: vc2)
let ThirdController = UINavigationController(rootViewController: vc3)
viewControllers = [FirstController, SecondController, ThirdController]
}
}
Nothing worked so far, and it always shows the selected index = 0.
I set the tab bar view controller as the initial view controller in the Main storyboard. Should I be doing this in the AppDelegate instead?
You are saying that
class MainTabBarController: UITabBarController {
so self refers to a UITabBarController, but you are setting the selected index of tabBarController of self:
self.tabBarController?.selectedIndex = 2
There are no tab bar controllers embedded in self. self itself is a tab bar controller! You can just set self.selectedIndex:
self.selectedIndex = 2
Also, you should do that in viewDidLoad instead of viewDidAppear, because viewDidAppear can happen many times (every time some modal controller is dismissed for example). viewDidLoad will only be called once.
I am trying to navigate to specific view controller but it is not working.
what i am doing is below
var viewControllers:[UIViewController]!
var firstView : UIViewController!
let storyboard = UIStoryboard(name: "Main", bundle: nil)
firstView = storyboard.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
viewControllers = [firstView]
#IBAction func BackAction(_ sender: Any) {
for aViewController in viewControllers {
if aViewController is FirstViewController {
self.navigationController!.popToViewController(aViewController, animated: true)
}
}
}
but not working .
Please help me where i am wrong.
Thanks
I have a view in my xib file which contain buttons. i want to move to a ViewController when i will press the button (#IBAction). I have used below code
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("About") as! AboutViewController
self.presentViewController(nextViewController, animated: true, completion: nil)
I am getting the error "Value of type 'SlideMenuView' has no member 'presentViewController'.
because my class is a UIView type :
class SlideMenuView: UIView {
}
so how can I navigate to other view controller.
That is beacuase the class you are trying to present from is a UIView and not a UIViewController. It has no Present method.
I'm guessing your view (SlideMenuView) is embedded inside a viewcontroller. what you need to do is implement a delegate, and inform your containing viewController to present next Viewcontroller.
code below:
#protocol SlideMenuViewDelegate: class {
func slideMenuViewAboutButtonClicked(menuView: SlideMenuView)
class SlideMenuView: UIView {
weak var delegate: SlideMenuViewDelegate?
#IBAction func aboutButtonClicked(sender: AnyObject) {
self.delegate?.slideMenuViewAboutButtonClicked(self)
}
now, in your viewController, implement this delegate method:
func slideMenuViewAboutButtonClicked(menuView: SlideMenuView) {
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("About") as! AboutViewController
self.presentViewController(nextViewController, animated: true, completion: nil)
}
Also, dont forget to assign the sliderMenuView object the viewcontroller as a delegate.
something like:
self.sliderMenuView.delegate = self // (self == the containing viewController
I did it in a different way. In class file
class SlideMenuView: UIView {
var navigationController: UINavigationController? // Declare a navigation controller variable
// And create a method which take a navigation controller
func prepareScreen(navController: UINavigationController)-> UIView {
navigationController = navController
let nibView = NSBundle.mainBundle().loadNibNamed("SlideMenuView", owner: self, options: nil)[0] as! UIView
self.addSubview(nibView)
return nibView
}
// In Button action
#IBAction func btnAction(sender: UIButton) {
var storyBoard = UIStoryboard(name: "Main", bundle: nil)
let nextViewController = storyBoard!.instantiateViewControllerWithIdentifier("NextViewController") as! UIViewController
navigationController?.pushViewController(nextViewController, animated: true)
}
}
// For calling from UIViewController
slideBarMenuIstance.prepareScreen(self.navigationController!)
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"
}
}