Exiting app and going back to home screen using swift 4 - ios

I am using a UITabbarController. I have 3 items/tabs inside the UITabbarController. Each tab depicts separate View controller. The list of views are as under
Tab 1: List View Controller
Tab 2: Favorite View Controller
Tab 3: Contacts View Controller
Now suppose I am on Tab 3 (Contacts View controller). And here I am showing my user a UIAlertController that has a button "Exit App".
When User will click on the Exit app, the user is supposed to go out from our application and will be taken to the home screen.
I have tried following snippets from SO but nothing is working for me.
self.view.window!.rootViewController?.dismiss(animated: true, completion: nil)
I even read to do exit(integer number) to exit the app but I read it also that it should not be done.
So I am really confused about what I need to do to exit app? How can I quit app and go back to home screen using Swift 4?

It's not a good idea to exit the app. The URL provided by #Cristik in comments also suggests that if apple will get to know about it they will send you a notice to remove it.
Better just keep the proper UIAlert message to tell the user what are the things required to use the app. Also proper UI navigation to first get all the required things for you business logic so that the user don't miss anything before using the app.
If you still want go with this then as #Cristik commented try this solution:
How does Booking.com close their app programmatically?

You can use:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let loginVcObj = storyboard.instantiateViewController(withIdentifier: "SignInVc") as! SignInVc
var vcArray = (applicationDelegate.window?.rootViewController as! UINavigationController).viewControllers
vcArray.removeAll()
vcArray.append(loginVcObj)
(applicationDelegate.window?.rootViewController as! UINavigationController).setViewControllers(vcArray, animated: false)

Related

How to open a Particular tab by default when VC loads, How to move to index Tab when child ViewController Opened in CAPSPageMenu?

I have implemented https://github.com/PageMenu/PageMenu library in Swift 4.2
My Screen look like below :
1.https://ibb.co/QdkFdMR
2.https://ibb.co/cksN3ww
When i click Edit button of Profile Details, i am navigating to a VC with name DoctorPersonalEdit by following code :
let personalDetail = self.storyboard?.instantiateViewController(withIdentifier: "DoctorPersonalEdit") as! DoctorPersonalEdit
self.parentNavigationController?.pushViewController(personalDetail, animated: true)
till here everything works properly after that when i click Save button i want to go to previous page i.e 1st screenshot how can i go back to previous page. Also , when Screen loads first time i have to highlights third tab Business Page. Could some one help me i tried searching library but couldn't find any solution.
Have you tried dismissing the VC ?
On your "saveBtn" IBAction do:
self.presentingViewController?.dismiss(animated: true, completion:nil)
How did you implement the tab? Do you switch between them with a Switch Case? If that's the case, you just have to change the default value.
Use this line of code
_ = navigationController?.popViewController(animated: true)

How to change a parent view by clicking a button inside of subview in swift (Xcode)

I am working on an app which needs a menu bar, it should be used in many different views, so here is what i did.
I make a subview which is the menu, it is loaded by other view in Main.storyboard.
Main.storyboard ----- this contains parent view
SimpleCustomView.xib ----- this is the subview
Here is the Problem:
How can I make a button inside of SimpleCustomView which can change the parent view in Main.storyboard? So the users can click on the menu to switch pages.
I have tried:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "PC") as UIViewController
// self.presentViewController(vc, animated: true, completion: nil)
//superview.presentViewController(vc, animated: true, completion: nil)
Neither 3rd line nor 4th line works.
So i got quite confused, how can i do it.
The general approach in a situation such as yours, where you want multiple views to show a certain view from a parent view, would be to send a notification from the child view when the button is clicked. The parent view would be listening for that particular message and then carry out an action - show the menu in this case.
Since I don't know enough about your particular set up, I don't want to hazard providing code which might not really work for you :) If you are able to share your project with us, then I can take a look and give you specific code which should work.

Swift 2 self.presentViewController vs segue for simple navigation

I am new to iOS Development and I am using swift2 to develop a simple web application whereby I am unsure of the behaviour of self.presentViewController.
In my MainViewcontroller I have the following codes to redirect user to login viewController
let storyboard = UIStoryboard(name: "Main", bundle: nil);
let signinViewController = storyboard.instantiateViewControllerWithIdentifier("SigninViewController") as! SigninViewController;
self.presentViewController(signinViewController, animated: true, completion: nil);
This set of codes work the way I want it to, which will redirect the user to signin page upon starting the application.
However in android development, I have to do a "finish();" to destroy my current stack, and I am unsure whether if I have to follow similar procedure in iOS Development.
Next, I have done some research on self.presentViewController versus segue as followed in the given article
UIStoryboardSegue versus presentviewcontroller?
So am I save to say that my approach in redirecting users from (Main_VC to SignIn_VC) is correct?
Your code is correct. You should not destroy presenting view controller in any way, it needs to be there when you get back from presented view controller.
If you do not plan to ever return the previous controller, you can simply replace it with new view controller as your window's (or navigation controller's) root. Since you are presenting sign in controller, this is probably not what you might want to do, just mentioning in for sake of completeness

How to pop from 3rd ViewController to the initial ViewController without NavigationControllers?

I know this is probably an easy task but I can't get my head around how to solve it. I'm not using a NavigationController by the way. Basically I have 3 view controllers in my app:
-LoginVC (this has a register button. when tapped, it goes to the SignupVC)
-SignupVC (if user signs up, it will push to the MainAppVC)
-MainAppVC (has a logout button)
For the transitions, I use the method: present(viewController, animated:, completion:)
When the user logs in via the LoginVC, he'll be presented the MainAppVC as expected. When he logs out, I'll dismiss the current VC (which is the MainAppVC) to send him back to the LoginVC.
Now here is the case where I have questions about. When the user does not have an account and signs up, this is the VCs he will pass through (LoginVC > SignupVC > MainAppVC). Once he registers successfully, he'll be presented the MainAppVC. Now once he logs out, he'll be transitioned from the MainAppVC to the SignupVC because I used the same dismiss method.
What I want to do is to send the user back to the LoginVC from the MainAppVC. How do I accomplish that without using a navigation controller in my project? How do popular apps (Facebook, Twitter, Instagram, etc) handle this in their apps?
One way I can think of is to perform a segue from 3rd to 1st VC but I think that's a dirty way since it just adds to the stack, instead of popping it off which is a potential issue.
There are three solutions.
1.Use window root view controller.Set root view controller between login and main view controller.
let loginSb = UIStoryboard(name: "Login", bundle: nil)
let loginVc = loginSb.instantiateInitialViewController()
window!.rootViewController = loginVc
2.Dismiss the sign up view controller the first time you present main view controller.And present the main view controller from login view controller.
3.Try to dismiss the sign up view controller in the completion block when you dismiss the main view controller.
I think the first one is best.
If are forced to NOT use a rootViewController (with UINavigationController), you should check in MainAppVC which one is the previous VC (Pseudocode in the example) and do:
Note: Swift 3 Code.
// If previous VC is LoginVC
dismiss(animated: true)
// else if previous VC is SignupVC
// here's what you want
presentingViewController?.presentingViewController?.dismiss(animated: true)
Hope that helped.
Another option is to use unwind segues.
In the ViewController that you want to go back to, implement a method as follows
#IBAction func unwindToLogin(segue: UIStoryboardSegue) {
}
Then in Storyboard, from the last ViewController right click and drag from the button (for example) to Exit and choose unwindToLoginWithSegue.
Note that you can also do this programatically. Here is a good tutorial.
Best approach is :
Dismiss SignUpVC once User Register successfully, Then from LoginVC present MainVC.
In SignupVC :
self.dismissViewControllerAnimated(true, completion: {
self.LoginVC!.present(MainVC, animated: true, completion:nil)
})
This approach is used mostly.

Push Notification open specific screen in TabBarController NavigationController revealViewController

Here is what I am trying to do.
When I receive the push notification and I tap I want to show a specific screen in my app. I found a lot about it but I am having trouble due to the complexity of the structure of my application.
Here is how the app is structured:
LoginViewController
RevealViewController (https://github.com/John-Lluch/SWRevealViewController)
UITabbarController
NavigationController
ViewController (This is a table view)
DetailViewContorller
I want to pass some arguments to the DetailViewContorller so I can make sure I get the right results when opening the screen.
Here is the screenshot of my app structure
application Folow
With the following code in my AppDelegate:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tb = storyboard.instantiateViewControllerWithIdentifier("TabBarVC") as! UITabBarController
tb.selectedIndex = 1
window?.rootViewController? = tb
I have managed to get to the tabbar when tapping on the notification but I am not happy with the results. I am still having the following issues:
the revealViewController is nil so I am not able to open my setting panel
I still don't get to the DetailViewController which is at the bottom of my view hierarchy
Any hint will be appreciated.
I had a similar issue although my flow was a bit different. I ended up handling Push Notification event (when user taps on it) and storing the object at the app delegate level. In each view controller that appeared after that (in ViewDidLoad() method) I would check for that object and figure out whether to redirect the flow to the next view controller. To help with this, my notifications had a type associated with them. Unfortunately, I was not able to find a better solution.
P.S. It also appears like you're instantiating View Controllers in code and I was using Storyboards. However, the basic idea is the same. I ended
#MK_Dev, Thanks for your suggestion but I was looking for something easier to manage.
This has actually helped me.
Get top most UIViewController
Here is what I did:
if var topControl = UIApplication.sharedApplication().keyWindow?.rootViewController {
while let presentedContreller = topControl.presentedViewController{
topControl = presentedContreller
}
if topControl.childViewControllers[0].isKindOfClass(MyCustomClassVC) {
// Check if the user is already on the VC we are trying to open
let chatController = topControl.childViewControllers[0] as! MyCustomClassVC
// ... any additional code you need to add here ...
}
}

Resources