I have been working on iOS application in swift from last 40-45 days. It has around 20 screens. I have implemented google map, payment gateway and many other UI component into it.
My problem is it is showing memory usage around 120 MB in flows which is very high for mobile devices. I did not used navigation controller and I have created all UI component programmatically.
In order to move from one view to another view, I have connected them via segue and in prepare for segue method I am sending data if needed. Given code is moving from one view to another
#IBAction func goToSearchFromHome(searchButton: UIButton) {
self.performSegueWithIdentifier("homeToSearchSegue", sender: self)
}
In order to come on previous page I am using following code:
#IBAction func goToHomePage(homeButton: UIButton) {
let vc = storyboard!.instantiateViewControllerWithIdentifier("homeScreen")
self.presentViewController(vc, animated: true, completion: nil)
}
Ideally, when moving from one screen to another, memory usage should include on that instance of view. What should I do in order to solve my problem?
Related
i have the following situation:
In my TabBarController i have multiple tabs and it all works fine, but:
The destination of one specific tab is dynamic.
If a certain condition matches, this specific tab should open a NavigationViewController.
If an other condition matches, this specific tab should open a ViewController.
Are there any built in solutions?
How can i modify the destination of a tab at runtime?
Greetings and thanks
Long long ago, in a galaxy far far away...
Segues didn't even exist. So yeah
The UITabBarController has a setter in which you can pass the new view controllers you want it to handle. You won't be able to decide what shows at the point of the tapping this way, but you'll be able to change the controllers as the condition changes.
open func setViewControllers(_ viewControllers: [UIViewController]?, animated: Bool)
If you however DO need to decide as the tab is tapped... You could have your tab controller direct to a controller that's essentially empty, and use view controller containment for that controller to have the 2 options on it, and have one of them hidden. Pretty doable from the storyboard with very little supporting code. I think I prefer this option.
If you would rather continue to use Segues, then you can perform a specific Segue depending on the state of some condition variable like this:
func presentAppropriateView() {
if condition {
performSegue(withIdentifier: "ToNavBar", sender: self)
} else {
performSegue(withIdentifier: "ToVC", sender: self)
}
}
write a delegate method which you want to perform on certain condition on runtime and call
[self.tabBarController setSelectedIndex:0];
where index could be of your choice
I am trying to refresh my viewcontroller (reload it ) using UIApplication.shared.keyWindow?.rootViewController as shown below in code, it works however when reloaded the novaigation controller is not there, I mean there a back button that can go to previous view controller it does not appear when I did that - any help
#IBAction func Save(_ sender: AnyObject) {
UIApplication.shared.keyWindow?.rootViewController = storyboard!.instantiateViewController(withIdentifier: "UploadPhotoviewcontroller")
}
Default back button, appearance and work in current navigationController navigation stack. If you change rootViewController, this action will destroy you current navigation stack and all previous controllers. And you cant go back.
Change the rootViewController be bad practic. I think you have a problems with the architecture
#jon when I try to comment it did not and I can not reply to your question as comment - I do not know why
Exactly that is the reason
I found the answer:
To deselect the picked image in elcimagepickercontroller use below code:
imagePicker.popToRootViewController(animated: true)
self.dismiss(animated: true, completion: nil)
func checkForRecipes(noRecords: Bool) {
//segue to addNewRecipe page
if noRecords == true{
print("Can't Find any Recipes!")
self.performSegue(withIdentifier: "ToAddNewRecipeVC", sender: self)
}else{
print("error, noRecords not equal to zero")
}
I am able to segue successfully via the storyboard but want to do so programmatically based on information returned from a delegate.
Upon running the app, the information from the delegate is successfully sent to the function "checkForRecipes" -i.e "noRecords" returns TRUE, but for some reason, the below line of code within that function does not seem to execute (and no errors are thrown):
self.performSegue(withIdentifier: "ToAddNewRecipeVC", sender: self)
The app starts up but stops at the main screen, whereas it should segue to the "AddNewRecipe" view controller.
The segue itself definitely has a segue ID of "ToAddNewRecipeVC". I have also tried dispatching to the main queue (to no avail) based on the following thread.
I'm stumped - what's going wrong here?
OK, it looks as though I have solved the problem. I embedded the main view controller into a navigation controller and now everything works as intended. I tried this same tactic earlier and it kept throwing up errors. grrr!
Anyway - thank you to all for the input!
Currently on my viewController : Upload, my button send the data to my database only if all the information are filled out, and I come back to the preview view (table View) with :
self.navigationController?.popViewControllerAnimated(true)
I would like, if it is possible, to come back to my main view on the tabBarController. I tried many things, like directly on the storyboard with Present modally segue to "TabBar controller", but I come back to the TabBar without sending my data to the database and without checking in the information are filled out..
How can I do it?
Thanks!
UITabBarController has a property selectedIndex with which you can switch the selected tab. So on completion after dismissing the UploadViewController you can run:
self.tabBarController?.selectedIndex = 0 // Index to select
It would probably be best to create a delegate for your UploadViewController to fire a function to do all the work in your previewVC on API call completion.
(Super late response...in case someone has similar questions, presumably in later version of Swift, such as mine which is Swift 5, iOS 13.2). Steps:
Be sure to set an id for your UITabBarController storyboard, e.g. "TabBarViewController"
Next, add the following to an action that has already been connected to a button:
let ID_TABBAR = "TabBarViewCOntroller"
#IBAction func returnToTabbar(_ sender: Any) {
let tabBarController = self.storyboard?.instantiateViewController(identifier:ID_TABBAR) as! UITabBarController
self.navigationController?.pushViewController(tabBarController, animated:true)
}
Referenced from one of the responses from this post.
Update: In case your Tab Bar View Controller also happens to be the root view controller, the two lines of the code in the returnToTabbar method above can be:
self.dismiss(animated:true, completion:nil);
self.navigationController?.popViewController(animated:true);
(ref.: See answer here, for Swift4 but works just fine in Swift5)
I have created a local notification in Swift which gives the option to end a current game without having to go back in to the app. That's all fine and works as it should. The issue I'm having is that if the user does this, I don't want them to go back to the Game view controller if that happens to be the last view that was open when the app entered the background. I would like them to go back to the app's Home view controller instead.
I expected to be able to add a perform segue to my Game view controller in the following way, should the criteria match. I tried adding it to viewDidAppear(), but it didn't work:
override func viewDidAppear(animated: Bool) {
if isThereACurrentGame() == false {
performSegueWithIdentifier("unwindToHomeScreen", sender: self)
}
}
Is this something to do with viewDidAppear() not being called when the app comes back to the foreground? If so, what might an alternative be?
P.S. My isThereACurrentGame() function works as it should, as does the performSegueWithIdentifier elsewhere in the view controller, so these aren't the cause of the problem.