Navigation controller is not working in multiple storyboard - ios

I have a login page a the beginning of my app. when user is granted I'll redirect it to another storyboard.
In this below photo1: the white screen check is user granted or not. if yes I'll redirect the to Photo2. else I'll redirect them to the login page ( red pages in photo1).)
In below Photo2:(I'll show a table view which contains some data. when the user clicks one of them, it goes to the next page (right one).)
And Photo3 is just to clarify Photo2.
The problem is Photo2 after a user clicked a row in the table view. the back button does not work (it is visible in the app)
The code below shows the white screen's code in Photo1:
if let token = UserDefaults.standard.string(forKey: ConstantsKey.token){
if !token.isEmpty{
let storyboard : UIStoryboard = UIStoryboard(name: "MainTabBar", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabBarVC")
let rootController = UINavigationController(rootViewController: vc)
rootController.navigationBar.barTintColor = UIColor.init(red: 229/255, green: 28/255, blue: 60/255, alpha: 1)
self.present(rootController, animated: true, completion: nil)
}else{
// let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "LoginVc")
self.present(vc, animated: true, completion: nil)
}
}else{
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "LoginVc")
self.present(vc, animated: true, completion: nil)
}
The code below shows the login page after the user is granted:
let storyboard : UIStoryboard = UIStoryboard(name: "MainTabBar", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabBarVC")
let rootController = UINavigationController(rootViewController: vc)
self.present(rootController, animated: true, completion: nil)
The code below shows the way I redirect the user to the page which has the problem in the photo 2:
let next = self.storyboard?.instantiateViewController(withIdentifier: "ShopVc") as! ShopViewController
self.navigationController?.pushViewController(next, animated: true)
I Also have added the code below to Delegate :
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage()
Am I doing something wrong here which might cause this problem?
////////////////////////////////////////////////////////////////
ANSEWER
I created a new project which works fine there! I think it was the xCode's problem!

restart your project , this could be an Xcode problem

Related

Transition Animation is not working Swift 5

I am trying to navigate from one view controller to other using tap gesture navigation. I want add transition animation into it. I tried with two ways but it didn't worked for me. -
First approach :
UIView.animate(withDuration: 0.5) { ()-> Void in
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let myTabBarController = storyBoard.instantiateViewController(withIdentifier: "profileViewController") as! ProfileViewController
var appDel = UIApplication.shared.delegate as! AppDelegate
appDel.window?.rootViewController = myTabBarController
self.view.layoutIfNeeded()
}
Second approach :
UIView.animate(withDuration: 0.25,
delay: 0.0,
options: [.curveEaseIn],
animations: {
let controller = self.storyboard!.instantiateViewController(withIdentifier: "mainMenuViewController") as! MainMenuViewController
self.addChild(controller)
self.view.addSubview(controller.view)
controller.didMove(toParent: self)
}, completion: nil)
Can anybody please tell me whats the solution ?
try this to present
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "profileViewController") as! ProfileViewController
self.present(nextViewController, animated:true, completion:nil)
If you present a ViewController then you can only Dismiss it, It can be done by below code
self.dismiss(animated: true, completion: nil)
To push
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "profileViewController") as! ProfileViewController
self.navigationController?.pushViewController(nextViewController, animated:true)
If you push a ViewController then you can only Pop it, It can be done by below code
self.navigationController?.popViewController(animated: true)

sending ui data in swift

I'm a bit beginner in SWIFT and right now I'm facing a problem whit UI. In this PHOTO I'm showing my UI to clarify what I'm saying . in part 1 I check if the user is logged in to his account or not, if yes it goes to part 3, if not it goes to part 2. when user login in part 2, I transfer the user to part 3.
part 1 and 2 should not have any navigation color, though the part 3 should have the navigation color.
Part 1:
if let token = UserDefaults.standard.string(forKey: ConstantsKey.token){
if !token.isEmpty{
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabBarVC")
let rootController = UINavigationController(rootViewController: vc)
self.present(rootController, animated: true, completion: nil)
}else{
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "LoginVc")
let rootController = UINavigationController(rootViewController: vc)
self.present(rootController, animated: true, completion: nil)
}
}else{
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "LoginVc")
let rootController = UINavigationController(rootViewController: vc)
self.present(rootController, animated: true, completion: nil)
}
Part 2:
let storyboard : UIStoryboard = UIStoryboard(name: "MainTabBar", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabBarVC")
let rootController = UINavigationController(rootViewController: vc)
self.present(rootController, animated: true, completion: nil)
I want to have that red color in part 3 ! but whenever I run the application in shows the defualt color of the navigation controller
does anybody knows how should I manage/handle this problem?
Then in Part 1:
if !token.isEmpty{
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabBarVC")
let rootController = UINavigationController(rootViewController: vc)
rootController?.navigationBar.barTintColor = UIColor.red
self.present(rootController, animated: true, completion: nil)
Part 2:
let storyboard : UIStoryboard = UIStoryboard(name: "MainTabBar", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabBarVC")
let rootController = UINavigationController(rootViewController: vc)
rootController?.navigationBar.barTintColor = UIColor.red
self.present(rootController, animated: true, completion: nil)
While logging in set
UserDefaults.standard.set(true,forKey: ConstantsKey.token)
And in routing page check this
if UserDefault.standar.bool(forKey: ConstantsKey.token){
//Go to home page
}else {
setUpNav()
//Go to login page
}
setting navigation
this one will set for whole app
func setUpNav(){
UINavigationBar.appearance().isTranslucent = false
UINavigationBar.appearance().tintColor = UIColor.red
UINavigationBar.appearance().barTintColor = UIColor.white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white,
NSAttributedStringKey.font: UIFont(name:"Cairo-Bold", size:22.0)!]
}
if you want for single VC,
write this inside that VC,
make sure that VC's root is navigationController
self.navigationController.navigationBar.barTintColor = .white
self.navigationController.navigationBar.tintColor = .red
Even if you haven't set any value, it doesn't crash !!

Navigation item disappears with popover

I have created a popup displaying a list in which I send the text to another viewcontroller, but when I close the popup, the Navigation Item disappears, and I have already searched for nothing to solve this problem. The code that sends the selected list item in the popover is this:
Shared.shared.filialNome = self.filiais[indexPath.row].razaoSocial
self.recebeCodigo = self.filiais[indexPath.row].codigo
Shared.shared.codigoFilial = self.recebeCodigo
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "AniversarioViewController") as! AniversarioViewController
self.present(newViewController, animated: true, completion: nil)
Type of following = Modal
I have tried to call Present as Popover but the error persists, it seems that it does not close the VC completely, somebody can help me.
Before opening the popover and
After opening the popover
It seems like, as you are presenting the view controller (and ViewControllers do not have navigation item until we embed it in navigation controller).
So you can embed the same ViewController in navigation controller in storyboard and then get the reference for that navigation controller and present the navigation controller like
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let navController = storyBoard.instantiateViewController(withIdentifier: "YourNavigationControllerIdentifier") as! UINavigationController
self.present(navController, animated: true, completion: nil)
Or if you don't want to embed you can do programmatically like
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "AniversarioViewController") as! AniversarioViewController
let navController = UINavigationController.init(rootViewController: newViewController)
self.present(navController, animated: true, completion: nil)

Swift: Prevent flicker when presenting login screen at startup

We have two storyboards in our app. The default view in storyboard #1 assumes the user has previously supplied valid credentials. If they have not done so we "redirect" to the login screen in storyboard #2:
let storyboard = UIStoryboard(name: "Authentication", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("LoginController") as UIViewController
presentViewController(controller, animated: true, completion: nil)
This works - but there is a flicker when this code runs where the default view briefly appears prior to the login view being displayed. How can you perform this action without a flicker?
Instead of presenting LoginController you have to set the respective ViewController as rootviewcontroller to the window in Appdelegate itself as folllows:
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
//Check for credentials,if value available make LoginStatus as true
if LoginStatus == true{
//Change Storyboard name "Main" to your "storyboard #1" name.
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
//Change Viecontroller name "My_Offer" to your "DefaultViewController name" name.
let vc = mainStoryboard.instantiateViewControllerWithIdentifier("My_Offer") as UIViewController
let navigationController = UINavigationController(rootViewController: vc)
self.window!.rootViewController = navigationController
}else{
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Authentication", bundle: nil)
let vc = mainStoryboard.instantiateViewControllerWithIdentifier("LoginController") as UIViewController
let navigationController = UINavigationController(rootViewController: vc)
self.window!.rootViewController = navigationController
}
self.window!.makeKeyAndVisible()
This will prevent from displaying default view before presenting LoginController.
Or else
In storyboard #1 create a DummyViewController(UIViewController) and make it as InitialViewController and set a Background image(Your SplashScreen Image) to DummyViewController .In viewdidload check for credentials,If You have value
let storyboard = UIStoryboard(name: "storyboard #1", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("default view ") as UIViewController
presentViewController(controller, animated: true, completion: nil)
if no credentials go with your given code
let storyboard = UIStoryboard(name: "Authentication", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("LoginController") as UIViewController
presentViewController(controller, animated: true, completion: nil)
this too prevents flicker but it is not good way to do.I suggest First Method setting rootviewcontroller.This may help you.Give it a try.
My suggestion is to set launch screen viewcontroller as rootviewcontroller of the application until the all your deciding factor get executed. This is one of the finest approach for async operation.

Programmatically navigate to another view controller/scene

I got an error message during navigating from first view controller to second view controller. My coding is like this one
let vc = LoginViewController(nibName: "LoginViewController", bundle: nil)
self.navigationController?.pushViewController(vc, animated: true)
The problem is I always got this kind of error message
2014-12-09 16:51:08.219 XXXXX[1351:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </var/mobile/Applications/FDC7AA0A-4F61-47E7-955B-EE559ECC06A2/XXXXX.app> (loaded)' with name 'LoginViewController''
*** First throw call stack:
(0x2efcaf0b 0x39761ce7 0x2efcae4d 0x31b693f9 0x31ac1eaf 0x3191e365 0x317fe895 0x318a930d 0x318a9223 0x318a8801 0x318a8529 0x318a8299 0x318a8231 0x317fa305 0x3147631b 0x31471b3f 0x314719d1 0x314713e5 0x314711f7 0x3146af1d 0x2ef96039 0x2ef939c7 0x2ef93d13 0x2eefe769 0x2eefe54b 0x33e6b6d3 0x3185d891 0x4ccc8 0x4cd04 0x39c5fab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I already found the answer
Swift 4
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "nextView") as! NextViewController
self.present(nextViewController, animated:true, completion:nil)
Swift 3
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("nextView") as NextViewController
self.presentViewController(nextViewController, animated:true, completion:nil)
Try this one. Here "LoginViewController" is the storyboardID specified in storyboard.
See below
let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("LoginViewController") as LoginViewController
self.navigationController?.pushViewController(secondViewController, animated: true)
XCODE 8.2 AND SWIFT 3.0
Present an exist UIViewController
let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.present(loginVC, animated: true, completion: nil)
Push an exist UIViewController
let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.navigationController?.pushViewController(loginVC, animated: true)
Remember that you can put the UIViewController Identifier following the next steps:
Select Main.storyboard
Select your UIViewController
Search the Utilities in the right
Select the identity inspector
Search in section identity "Storyboard ID"
Put the Identifier for your UIViewController
If you want to navigate to Controller created Programmatically, then do this:
let newViewController = NewViewController()
self.navigationController?.pushViewController(newViewController, animated: true)
If you want to navigate to Controller on StoryBoard with Identifier "newViewController", then do this:
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
self.present(newViewController, animated: true, completion: nil)
Swift3:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController("LoginViewController") as UIViewController
self.navigationController?.pushViewController(vc, animated: true)
Try this out. You just confused nib with storyboard representation.
You can move from one scene to another programmatically using below code :
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let objSomeViewController = storyBoard.instantiateViewControllerWithIdentifier(“storyboardID”) as! SomeViewController
// If you want to push to new ViewController then use this
self.navigationController?.pushViewController(objSomeViewController, animated: true)
// ---- OR ----
// If you want to present the new ViewController then use this
self.presentViewController(objSomeViewController, animated:true, completion:nil)
Here storyBoardID is value that you set to scene using Interface Builder.
This is shown below :
See mine.
func actioncall () {
let loginPageView = self.storyboard?.instantiateViewControllerWithIdentifier("LoginPageID") as! ViewController
self.navigationController?.pushViewController(loginPageView, animated: true)
}
If you use presenting style, you might lose the page's navigation bar with preset pushnavigation.
Programmatically there are different ways based on different situations
load storyenter code hereboard nib file
let yourVc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "YourViewController") as! YourViewController;
self.present(yourVc, animated: true, completion: nil)
Load from xib
let yourVc = YourViewController.init(nibName: "YourViewController", bundle: nil)
self.present(yourVc, animated: true, completion: nil)
Navigate through Segue
self.performSegue(withIdentifier: "your UIView", sender: self)
let VC1 = self.storyboard!.instantiateViewController(withIdentifier: "MyCustomViewController") as! ViewController
let navController = UINavigationController(rootViewController: VC1)
self.present(navController, animated:true, completion: nil)
XCODE 9.2 AND SWIFT 3.0
ViewController to NextViewcontroller without Segue Connection
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "NextViewController") as! NextViewController
self.navigationController?.pushViewController(nextViewController, animated:true)
or
let VC:NextViewController = storyboard?.instantiateViewController(withIdentifier: "NextViewController") as! NextViewController
self.navigationController?.pushViewController(VC, animated: true)
You can do navigation between view controllers using code with the help of storyboard and storyboardId of the view controller.
This code is for Swift 3:
let signUpVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
self.navigationController?.pushViewController(signUpVC, animated: true)
In addition to the good answers above to set the navigation view controller on top of your screen on your app, you can add it to your AppDelegate.swift file inside the block as follows
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow()
window?.makeKeyAndVisible()
window?.rootViewController = UINavigationController(rootViewController: LoginViewController())
return true
}
let vc = DetailUserViewController()
vc.userdetails = userViewModels[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
I'm not sure try below steps,i think may be error occurs below reasons.
you rename some files outside XCode. To solve it remove the files from your project and re-import the files in your project.
check and add missing Nib file in Build phases->Copy bundle resources.finally check the nib name spelling, it's correct, case sensitive.
check the properties of the .xib/storyboard files in the file inspector ,the property "Target Membership" pitch on the select box,then your xib/storyboard file was linked with your target.
such as incorrect type of NIB.Right click on the file and click "Get Info" to verify that the type is what you would expect.
I Give you my code to make a transition.
In this example the action is connecting to an UIButton. So don't forget to set it.
Don't forget to set the name of your ViewController in the transition method.
Don't forget to set your storyboard too. Your need to have one view per viewController. Connect each ViewController to each view in storyBoard. You can see on the screenshoot bellow
class PresentationViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var playButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
let image = UIImage(named: "YourPlayButton") as UIImage?
playButton.frame = CGRectMake(0, 0, 100, 100)
playButton.center = CGPointMake(self.view.frame.width/2, self.view.frame.height/2)
playButton.addTarget(self, action: "transition:", forControlEvents: UIControlEvents.TouchUpInside)
playButton.setBackgroundImage(image, forState: UIControlState.Normal)
self.view.addSubview(playButton)
}
func transition(sender:UIButton!)
{
println("transition")
let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("YourSecondViewController") as UIViewController
let window = UIApplication.sharedApplication().windows[0] as UIWindow
UIView.transitionFromView(
window.rootViewController!.view,
toView: secondViewController.view,
duration: 0.65,
options: .TransitionCrossDissolve,
completion: {
finished in window.rootViewController = secondViewController
})
}
}
If you are building UI without drag and drop (without using storyboard)
and want to navigate default page or ViewController.swift to another page?
Follow these steps
1) add a class (.swift)
2) Import UIKit
3) Declare class name like
class DemoNavigationClass :UIViewController{
override func viewDidLoad(){
let lbl_Hello = UILabel(frame: CGRect(x:self.view.frame.width/3, y:self.view.frame.height/2, 200, 30));
lbl_Hello.text = "You are on Next Page"
lbl_Hello.textColor = UIColor.white
self.view.addSubview(lbl_Hello)
}
}
after creating second page come back to first page (ViewController.swift)
Here make a button in viewDidLoad method
let button = UIButton()
button.frame = (frame: CGRect(x: self.view.frame.width/3, y: self.view.frame.height/1.5, width: 200, height: 50))
button.backgroundColor = UIColor.red
button.setTitle("Go to Next ", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.view.addSubview(button)
now define buttonAction method outside of viewDidLoad() in same class
func buttonAction(sender: UIButton!)
{
let obj : DemoNavigationClass = DemoNavigationClass();
self.navigationController?.pushViewController(obj, animated: true)
}
Keep one thing that i forget
in main.storyboard there is a scene with a arrow,
select that arrow and press delete button
now drag and drop a navigationcontroller and delete tableview which comes with navaigation controller.
select navigationcontroller press control on keyboard and drag it in to another scene on storyboard that is ViewController.
This mean that your viewcontroller become root viewcontroller
hope this help you
Thanks
in main.storyboard , drag and drop navigationcontroller,
let signUpVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
// self.present(signUpVC, animated: false, completion: nil)
self.navigationController?.pushViewController(signUpVC, animated: true)
Swift 4.0.3
#IBAction func registerNewUserButtonTapped(_ sender: Any) {
print("---------------------------registerNewUserButtonTapped --------------------------- ");
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "RegisterNewUserViewController") as! RegisterNewUserViewController
self.present(nextViewController, animated:true, completion:nil)
}
Change our Controller Name RegisterNewUserViewController
I think you are looking for something like this:
let signUpViewController = SignUpViewController()
present(signUpViewController, animated: true, completion: nil)
If you want full screen of the new page:
present(signUpViewController, animated: true, completion: nil)
Hope this helps :)

Resources