segue back with NavigationBar - ios

Hello I am in Viewcontroller B with its NavigationBar, button pressed in Viewcontroller B goes to Viewcontroller C (I don't want NavigationBar in Viewcontroller C)
let vc = self.storyboard?.instantiateViewController(withIdentifier: "viewC") as! ViewcontrollerC
vc.passAction = "saveedit"
vc.passName = passName
self.present(vc, animated: true, completion: nil)
When I click save Button in ViewcontrollerC I should go back to ViewcontrollerB with ViewcontrollerB NavigationBar
let vc = self.storyboard?.instantiateViewController(withIdentifier: "viewB") as! ViewcontrollerB
vc.passName = "\(firstNameTxt.text!)\(" ")\(lastNameTxt.text!)"
self.present(vc, animated: false, completion: nil)
Here the problem is When I go back to ViewcontrollerB I don't see NavigationBar there.
EDITED
class ViewcontrollerB : UpdateDataDelegate {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated);
self.navigationController?.isNavigationBarHidden = false
}
#IBAction func click_edit(_ sender: Any) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "patientPersonalData") as! patientPersonalDataVC
vc.passName = passName
vc.passAction = "saveedit"
self.navigationController?.pushViewController(vc, animated: true)
}
func loadData() {
}
}
//ViewcontrollerC
protocol UpdateDataDelegate {
func loadData()
}
class Viewcontroller C {
var delegate: UpdateDataDelegate?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = true
}
fun click_save() {
self.navigationController?.popViewController(animated: true)
self.delegate?.loadData()
}
}

It seems that you create a new ViewcontrollerB.
Try this to go back to ViewcontrollerB.
self.dismiss(animated: true, completion: nil)

Why don't you simply dismiss ViewcontrollerC on pressing Save button?
In ViewcontrollerC:
var closure: ((String)->())? //Set this closure when you present ViewcontrollerC from ViewcontrollerB
func save()
{
self.dismiss(animated: true) {[weak self] in
self?.closure?("Your_Data")
}
}
This will move you back to ViewControllerB where the navigation bar is already present.
You don't need to hide/show the navigation bar anywhere, neither while presenting ViewControllerC, nor when dismissing it.

Try to present it using navigation controller
let vc = self.storyboard!.instantiateViewController(withIdentifier: "viewC") as! ViewcontrollerC
let navController = UINavigationController(rootViewController: vc)
self.present(navController, animated:true, completion: nil)
and add the following line in your ViewcontrollerC's viewWillAppear method.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = true
}
when leave from ViewcontrollerC's viewWillDisAppear method.
override func viewWillDisAppear(_ animated: Bool) {
super.viewWillDisAppear(animated)
self.navigationController?.isNavigationBarHidden = false
}

I just have posted code dedicated on UINavigationBar appearance management on github. check out RRViewControllerExtension, it will solve your problem gracefully.
with RRViewControllerExtension all you have to do is just override method in your viewcontroller.
//override any of the methods below in your viewcontroller's .m file to make specific navigation bar appearance
-(BOOL)prefersNavigationBarHidden;
-(BOOL)prefersNavigationBarTransparent;
-(nullable UIColor *)preferredNavatationBarColor;
-(nullable UIColor *)preferredNavigationItemColor;
-(nullable UIImage *)preferredNavigationBarBackgroundImage;
-(nullable NSDictionary *)preferredNavigationTitleTextAttributes;

Try this .. unhide navigationBar in viewWillAppear of viewControllerC and hide it in viewWillAppear of viewControllerB .
//ViewController C
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = true
}
//ViewController B
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated);
self.navigationController?.isNavigationBarHidden = false
}
try this then
//ViewController C
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
//ViewController B
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated);
self.navigationController?.setNavigationBarHidden(false, animated: true)
}

Related

hidesBottomBarWhenPushed hides TabBar forever

I use Xcode 11.2 and the project minimum iOS deployment target is iOS 12.4.
I have a TabBarController on root page and on one of the tabs I have FirstViewController. When I push SecondViewController from FirstViewController, I want the tab bar to be hidden. I used hidesBottomBarWhenPushed property to hide the tab bar.
The tab bar is hidden when I push SecondViewController but when I pop the SecondViewController and move back to FirstViewController, the tab bar is still hidden.
I tried several ways to set hidesBottomBarWhenPushed to false when moving back to FirstViewController but none of the tries worked.
How can I re display tab bar when popped back to FirstViewController?
class FirstViewController: UIViewController {
#IBAction func buttonTap(_ sender: Any) {
let vc2 = SecondViewController()
// Set to Hide TabBar
hidesBottomBarWhenPushed = true
navigationController?.pushViewController(vc2, animated: true)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// This Does Not Work
hidesBottomBarWhenPushed = false
}
}
class SecondViewController: UIViewController {
/*
All The Followings Does Not Work
*/
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
hidesBottomBarWhenPushed = false
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
hidesBottomBarWhenPushed = false
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
hidesBottomBarWhenPushed = false
}
}
The key was to set hidesBottomBarWhenPushed to true from outside of the SecondViewController.
The code below was all I needed to write.
class FirstViewController {
func pushSecondViewController {
let vc = SecondViewController()
vc.hidesBottomBarWhenPushed = true // <- Here
navigationController?.push
navigationController?.pushViewController(vc, animated: true)
}
}

Dismiss ViewController presented modally when tab is changed

I have a UITableViewControllerthat presents a UIViewController modally when didSelectRowAtis invoked.
My application is wrapped in a UITabBarController.
I would like to dismiss the UIViewController when a user changes tabs.
I have tried to call dismiss on my controller like so, but this does not work.
let vc = VimeoController()
....
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
vc.dismiss(animated: true) {
print("dismissed")
}
}
...
fileprivate func presentModal() -> Void {
vc.modalPresentationStyle = .overCurrentContext
present(vc, animated: true, completion: nil)
}
Place your dismiss call within the viewDidDisappear lifecycle hook of your VimeoController controller instead.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
dismiss(animated: true, completion: nil)
}

How to show image in overCurrentContext view in the ViewController2.swift class?

How to show image in overCurrentContext view in the ViewController2.swift class ? I am doing this correctly when i worked manually but not doing when i using this programmatically in swift.
ViewController1.swift code -
#IBAction func btnImage(_ sender: Any)
{
let imageVC = self.storyboard?.instantiateViewController(withIdentifier: "ImageVC") as! ImageVC
self.navigationController?.pushViewController(imageVC, animated: true)
}
ViewController2.swift code -
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.navigationController?.modalPresentationStyle = .overCurrentContext
}
I want this background alpha 0.7 and using .overCurrentContext
Output -
You are pushing your viewController, Instead you should present it with modalPresentationStyle .overCurrentContext. Do something like this:
#IBAction func btnImage(_ sender: Any)
{
let vc = self.storyboard?.instantiateViewController(withIdentifier: "ImageVC") as! ImageVC
vc?.view.backgroundColor = UIColor.black.withAlphaComponent(0.7)
vc?.modalPresentationStyle = .overCurrentContext
vc?.navigationController?.isNavigationBarHidden = true
self.navigationController?.present(vc, animated: true, completion: nil)
}
For more information you can read more about modalPresentationStyle in Apple Docs.
Hope it helps!!

UINavigationController crash UI on swipe action (black screen, video inside)

I have a UIViewController which is pushed from navigationController that uses custom left/back button with interactivePopGestureRecognizer, however, when I click a row from tableview my app sometimes stucks and after pressing home button and going background then reopening the app, it continues but swipe action of navigationcontroller becomes weird. Here is the video of what am I saying;
https://streamable.com/xvl38
//This is the function that I use to open chat from tableview on didSelectRowAt
func openChat(with nick: String, isFromConversationList: Bool) {
guard let chatVC = UIStoryboard(name: "Main", bundle: .main).instantiateViewController(withIdentifier: "ChatViewController") as? ChatViewController,
let rootNC = UIApplication.shared.keyWindow?.rootViewController as? UINavigationController else {
return
}
rootNC.pushViewController(chatVC, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.interactivePopGestureRecognizer?.delegate = nil
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
}
What can be the reason for that?

Swift: Not able to dismiss modally presented LoginViewController

As SplitViewController loads, I am showing a Login Screen. On successful login, I need to go back to parent view controller. Somehow dismissal is not working for me. Here is the code:
ParentViewController:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if !appDelegate.loggedIn {
self.performSegueWithIdentifier("loginScreen", sender: self)
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
Child ViewController:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.loggedIn = true
self.dismissViewControllerAnimated(true, completion: nil)
The dismissal part never works. It just hangs on Login Screen.
Try one of the following:
1) remove self. keep only dismissViewControllerAnimated(true, completion: nil)
or remove self. and make it:
2) presentingViewController.dismissViewControllerAnimated(true, completion: nil)
or remove self. and try:
3) presentedViewController.dismissViewControllerAnimated(true, completion: nil)
Try this in your parent view controller:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if !appDelegate.loggedIn {
let loginVC: UIViewController = self.storyboard!.instantiateViewControllerWithIdentifier("LoginViewController") as UIViewController
loginVC = UIModalTransitionStyle.CoverVertical
self.parentViewController?.presentViewController(loginVC, animated: true, completion: nil)
}
}
You're instantiating the new view controller by its own name rather than by the segue name.

Resources