I have a problem that I have not seen addressed in this particular way before, so hopefully someone can help me with it. Let's say I have a tab bar app with four views, one on each tab. Obviously the app will be forced to launch with the view controller it is told to launch with, but after that, it's up to the user to select which tab (view) to load next.
The problem comes from the fact that I would like to show a view on each tab ONLY the first time that particular view is loaded. Normally, you'd do this:
BOOL foo = [[NSUserDefaults standardUserDefaults]boolForKey:#"previouslyLaunched"];
if (!foo)
{
NSLog(#"FirstLaunch");
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:#"previouslyLaunched"];
///Do first run view initializaton here////
}
However, doing that once sets the NSUserDefault for all of the app, meaning that only the view for tab 1 will show and not the other three. So, my question is, how do I show a view for each of my four tabs only the first time each view loads? This is a complicated question because the user is able to select any tab in any order, so I can't guide them down a path, I think.
Would I have to use a different key for each view? Would that work? It seems like that might be the best course of action here, but this is my first time working with NSUserDefaults, so I'm a little lost.
Any and all help is much appreciated!
Use a different key for each view:
e.g. viewController1PreviouslyLaunched, viewController2PreviouslyLaunched... etc
Related
OK. I haven't actually seen how to do this anywhere. It may be a question of "You can't get there from here." or "Holy ##$! That is such a disgusting hack it should be taken behind the woodshed and shot!".
I have a tabbed Swift 3 iOS app that will dynamically update the Tab Bar images of selected pages as the page state changes.
I do that sort of like this:
if let navController = self.navigationController as? MyNavController {
navController.tabBarItem.image = navController.tabBarImage
navController.tabBarItem.selectedImage = navController.tabBarImage
}
The tabBarImage is actually a calculated property. This snippet is called within a UI callback that updates when the state changes.
This works great.
When in the MoreViewController, though, not so great. Those images remain stubbornly static, no matter what I do.
I have done some exploration of the MoreViewController. I can get at the tableView and the cells, but that smells like the kind of hack that will get my app taken behind the woodshed by the Blue Meanies at App Review.
Is there a proper way to do this?
You can use Notification and pass the images within a Dictionary as a Notification object. Then you can get different tabBarImage with different key value at once.
OK. I figured out how to do it.
I was crawling back along the navigation controller path; which worked fine for items not in the more space.
I fixed it by crawling forward from the tab bar controller, instead:
self.tabBarController?.viewControllers?[MySelectionIndex].tabBarItem.image = self.tabBarImage
self.tabBarController?.viewControllers?[MySelectionIndex].tabBarItem.selectedImage = self.tabBarImage
I have 2 views controlled by a tab bar controller.
The issue that I am having is that on returning to my 1st tab from my 2nd, I ideally need all of the 1st view's data to have reloaded based on the changes I made in the 2nd tab.
It is possibly better not to explain why, as my fumbled attempts at over-complicated code with numerous work-arounds will likely alarm you.
So basically, can i get viewDidLoad to redo itself when i go back to the view from another tab?
EDIT: and the answer is: viewWillAppear instead of viewDidLoad i think (can't answer own question for 8 hours)
Rather than reload every time on viewDidAppear, in most cases you're better off sending a message to view 1 telling it to reload next time it appears. This avoids unnecessary reloads (which can be bad for user experience and use unnecessary bandwidth). There are a number of ways to do this depending on the screen flow in your app. One way to do it would be:
-create an ivar BOOL shouldReload on view 1
-whenever something happens on view 2 (or anywhere else in the application) that requires a reload of view 1 post a message to [NSNotificationCenter defaultCenter] called something like "View1ShouldReload".
-on load of view 1 set the shouldReload flag to NO and start listening
-on the notification selector, set shouldReload to YES
-on viewDidAppear check if (shouldReload) then do the reload.
There are many other ways to do this (like delegates, singletons, whatever), but this is a simple way to make your app work more efficiently.
I have a TabBar Application with 2 tabs saving/fetching data to and from CoreData. The problem that I am having is that when the form has been filled and the user has touched the save button the view is not re-loaded or re-initialised. All I want is for the view to be ready for the user to repeat the process with the next set of information. I am probably not thinking about this in the correct way so a pointer in the right direction would be very much appreciated...
Do I need to manually set everything including the managedObjectContext etc. to nil? Or is there something that I can do with methods like viewWillDisappear that will elegantly help me to "re-initialise" that specific tab?
I ave read up the Apple docs on view hierarchies, and life cycles but I just seem to have confused myself...
Thanks in advance for any suggestions, referrals to code or even recommendations on relevant reading material.
It sounds like what you want to do is reload any data to their default states when the user taps a button. Unfortunately, you'll have to do this manually, setting each IBOutlet's value to a meaningful default (probably the empty string).
There are two ways I can think of that would help make this more elegant:
Use an IBOutletCollection and fast enumeration to loop over all the IBOutlets and not have a bunch of code to do each one individually.
If you're switching tabs in between these events, you can something neat and use your app delegate as your UITabBarControllerDelegate for the tabBarController:didSelectViewController: to call the clearing-out method for you instead of relying on viewDidAppear.
I already had a question like this, but I already deleted it anyway.
I have very simple app that has a root view controller and it switches between two other view controller views. So in my root view controller, It lazy loads the instances of the two other view controllers. Each time the switch button in the toolbar is pressed, the current view controller being displayed (its view) is unloaded (set to nil), and the new one is loaded and added to the subview.
Since I load my view controllers and unload at specific times, the lazy loading code being in the getters is very confusing because I don't actually want to load them right when I use them, I need to load them before so the flip animation will look good. So I think I want to make loadFirstVC and loadSecondVC methods to load the view controllers. Is this a good idea?
The main reason for lazy-loading is NOT to defer loading that will definitely occur. It is for deferring loading that may never be needed. (It's also good for forcing reloads when the data has changed, but that's not your issue here.)
Example: Let's say you have a bunch of data about a person, including a photo, which is stored in an external file. But the photo will only be displayed if the user goes to a subview, so why load the photo from its file until you know for sure that the subview is going to appear? Boom, use lazy loading.
By the time you KNOW you want to load a certain piece of data, it's unlikely to matter very much when exactly you load it.
When does it matter? Well, that's really a matter of optimization. There's a saying you may have run across; if you haven't, this is as good a time as any: "Premature optimization is the root of all (programming) evil."
So ask yourself two questions:
Will the piece of data definitely be needed? If NO, proceed with the lazy-loading technique. If YES, go to question 2.
Does it MATTER when I load the data? [An example would be, it's huge and I don't want to load it until I've UNLOADED something else to make room for it] If NO, put it any place that works. If YES... Come back and ask us again, and provide more details.
...I suspect this doesn't answer your original question, but it sounds like you may be asking the wrong question in the first place. Apologies if I'm mistaken.
I am having trouble finding some information on persistence in iPhone apps. I am creating a tab based - navigation based app and want the application to save the current location when the app quits. For example if the user is in tab 1, several tiers into the navigation controller and the app quits, I would like the app to load up in the same place the next time it loads.
If anyone can point me in the direction of a good book/tutorial that would be great.
Cheers
Just to make it clear, I know that I would need to save the data somewhere and that NSUserDefaults seems to be the best way to do this. What is confusing me is what to actually save when the app is closed and then how to load it so that the correct view is loaded.
NSUserDefaults
http://icodeblog.com/2008/10/03/iphone-programming-tutorial-savingretrieving-data-using-nsuserdefaults/
Obviously, you'll need to save the tab you're displaying, and whatever sort of data storage you want to use to manually determine where the user is. If you're using a drill-down sort of system where your data is in arrays that the user opens, then I would suggest saving an NSIndexPath of the items the user clicked on to get to his current position.
Then, on app startup, first switch to the correct tab, then load the index path and create the necessary views and set the navigation controller's stack using [navigationController setViewControllers:animated:]