Presenting a specific view controller once immediately after launch screen closes - swift

I have a 1-screen tutorial View Controller. I want this tutorial VC to show only once (userdefaults), but I want a smooth transition from when the launch screen finishes -> tutorial VC.
Right now - the launch screen finishes, then the main interface of the App shows for a split second, then the tutorial VC shows up. I want to remove this "flashing" of the main interface.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !didShowTut {
fireTutorial()
didShowTut = true
}
}
func fireTutorial() {
let tutVC = UIStoryboard(name: "FirstTutorial", bundle: nil).instantiateViewController(withIdentifier: "TutorialSBID") as UIViewController
tutVC.modalPresentationStyle = .overCurrentContext
self.present(tutVC, animated: false, completion: nil)
}
Any help to create a smooth transition from Launch screen -> Tutorial VC would be appreciated.

You are presenting the tutVC on the viewDidAppear func which is executed after the screen has been loaded.
try calling the fireTutorial() on override func viewDidLoad() or on the override func viewWillAppear(_ animated: Bool) methods that get executed before the screen is loaded.

I went with a slightly different approach to solve this.
I embedded the main app VC in a navigation controller, then pushing the tutorialVC in App Delegate didFinishLaunchingWithOptions.
let tutorialVC = UIStoryboard(name: "FirstTutorial", bundle: nil)
let firstVC = tutorialVC.instantiateViewController(withIdentifier: "TutorialSBID") as UIViewController
if let navigationController = self.window?.rootViewController as? UINavigationController
{
navigationController.pushViewController(firstVC, animated: false)
}
return true

Write this code in viewWillAppear or viewWillLayoutSubviews() instead of viewDidAppear

Related

xcode swift4 how do I change the page in viewdidload

I cannot use segue on viewDidLoad.
I already check the segue is worded on another func.
When load the view check some condition then change view this is what I want.
override func viewDidLoad(){
super.viewDidLoad()
performSegue(withIdentifier: "go" , sender: self)
}
If you want to push your view controller on view did load then just use this code.
let storyBoard : UIStoryboard = UIStoryboard(name: "your_StoryBoard", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "VC_Identifier") as! TargerViewController
self.navigationController?.pushViewController(nextViewController, animated: true)
OR
You can set the target viewcontroller as root viewcontroller by check any condition.
Hope it will helps you out.
i prefer that don't use segue use as below
let storyboard = UIStoryboard(name: "YourStoryboard", bundle: nil)
let VC = storyboard.instantiateViewController(withIdentifier: "Your Identifier") as! Your ViewController
self.present(VC, animated:true, completion:nil)
user this for redirect from One VC To Another VC
Replace viewDidLoad to viewDidAppear solved my problem
override func viewDidAppear() {
super.viewDidLoad()
performSegue(withIdentifier: "go" , sender: self)
}

Swift: Gesturing doesn't bring back the TabBar

I am trying to move back from a ViewController (simple text page) to a main ViewController with a TabBar at the bottom using gesturing.
The gesture works as I return to the original main screen but there is no TabBar.
In the simple ViewController I use this code to go back to the originating ViewController.
#objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizerDirection.right:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "AboutViewControllerID")
self.present(controller, animated: true, completion: nil)
if let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "AboutViewControllerID") as? AboutViewController
{
present(vc, animated: true, completion: nil)
}
default:
break
}
}
}
In the ViewController with the TabBarController I have tried the following lines to rejuvinate the TabBarController but without any joy.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
tabBarController?.tabBar.isHidden = false
NSLog("TabBar true")
}
Any ideas?
First if you want to go-back don't use present as it will add the same VCS twice in the stack , you have to use unwindSegue/dismiss , or load the tabBar itself with id
self.dismiss(animated: true) {
// use this if it's not directly behind the dismissed VC
let tab = storyboard.instantiateViewController(withIdentifier: "tabBarID") as! UITabBarController
UIApplication.shared.keyWindow?.rootViewController = tab
}
//

Hiding Bottom Bar When Pushed - Animation freezing on Iphone X

I've encountered an issue that I cannot figure out for the life of me. The issue is only happening on the iPhone X. I've added a little video since its difficult to explain exactly whats happening.
I've also added a screenshot of my storyboard so you can see the flow.
Pretty much were experiencing a freeze when the tab bar is being hidden. It only happens when we visit the category VC (which is presented modally using a segue, it is also embedded in a navigation controller.)
** I'm still new to iOS development so if I'm doing anything terribly wrong feel free to share :)
Video:
https://youtu.be/HC14zFxh-HM
Code that sends to reader:
#IBAction func sendToReader(_ sender: Any) {
let myVC = storyboard?.instantiateViewController(withIdentifier: "ReaderRootVC") as! ReaderRootVC
myVC.book = self.book
myVC.hidesBottomBarWhenPushed = true
navigationController?.pushViewController(myVC, animated: true)
}
Code that closes Category VC:
#IBAction func navigationCancelBtnPressed(_ sender: Any) {
self.navigationController?.dismiss(animated: false, completion: nil)
}
Storyboard:
In your ReaderRootVC,
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Hide the Tab Bar
self.tabBarController?.tabBar.isHidden = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Show the Tab Bar
self.tabBarController?.tabBar.isHidden = false
}

How to correctly display a tab controller in swift

I'm making a login screen for my app and everything works as intented until I try to present my main view after the login(which uses a Tab Bar Controller).
The only problem is that it displays just the first item on the tab bar. I have to press the other buttons for the to appear.
Im using this code:
//after login...
var storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var vc: TabBarViewController = storyboard.instantiateViewControllerWithIdentifier("MainController") as! TabBarViewController
self.presentViewController(vc, animated: true, completion: nil)
My guess is that I need to load them all at the same time, but I dont know...
This is how I did it recently. I loaded my tabBarController and the login screen together, once the user has logged in (or completed the first screen experience) you can modally dismiss the controller.
func showloginView() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let loginViewController: LoginTableViewController = storyboard.instantiateViewControllerWithIdentifier("LoginTVC") as! LoginTableViewController
self.window?.makeKeyAndVisible()
var viewController = storyboard.instantiateViewControllerWithIdentifier("LoginTVC") as! LoginTableViewController
let nav = UINavigationController(rootViewController: viewController)
self.window?.rootViewController?.presentViewController(nav, animated: true, completion: nil)
}
for displaying your tabBarController and editing of any of the tabBarItems
let tabBarController = self.window?.rootViewController as? UITabBarController
let tabBarRootViewControllers: Array = tabBarController!.viewControllers!
let nav = tabBarRootViewControllers[0] as? UINavigationController
Hope this helps =)
If you link an UIButton, you can open a UITabBarController using this (providing you're using a Storyboard)
#IBAction func openTabBar(sender: AnyObject) {
var tabBarController = self.storyboard?.instantiateViewControllerWithIdentifier("tabBarController") as! UITabBarController
self.presentViewController(tabBarController, animated: false, completion: nil)
}
That'll pop the current view and open the tab bar controller.

Content under a login View is visible for a fraction of second

I have a view displaying some content, which is password protected. In viewWillAppear a variable gets checked, to see if the user is properly logged in :
override func viewWillAppear(animated: Bool) {
if (!Config.userLoggedIn) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let loginVC = storyboard.instantiateViewControllerWithIdentifier("loginVC") as! UIViewController
loginVC.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
self.navigationController!.presentViewController(loginVC ,animated: true, completion: nil)
}
}
It works, but the content underneath is visible for a short fraction of a second. How can I present the loginVC without revealing the content underneath.
I cannot put it in viewDidLoadbecause all this is part of a TabBarController, and the views might already be in memory and viewDidLoad is only called once
Simple solution. Hide whole view in viewDidLoad then show it back in viewViewAppear if user is correctly logged in
override func viewDidLoad(){
self.view.hidden = true
}
override func viewWillAppear(animated: Bool) {
if (!Config.userLoggedIn) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let loginVC = storyboard.instantiateViewControllerWithIdentifier("loginVC") as! UIViewController
loginVC.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
self.navigationController!.presentViewController(loginVC ,animated: true, completion: nil)
}else{
self.view.hidden = false
}
}