I'm making a role-playing game, and I want to have a Map View and a Battle Screen. With the possibility of other screens as well.
I thought the best way to achieve this was to use multiple NIB files.
When I prototyped this by have one view that creates content, switching to the next view, and then back, the content on the original view was reset.
How do I make it so that the first view doesn't reset the data each time it's loaded?
Your question is a little vague. A view usually does not get "reset" unless you run into a low memory warning. That said, even then it's just up to you to keep the right references and setup your view correctly. Maybe have a read through Apple documentation or provide some code. Adrian also has a good write-up about this.
Related
I'm creating a project which uses a UICollectionView. As the user selects a cell this slides them to another UICollectionView of similar nature. Ive been noticing that no matter how I go about this I wind up with mountains of memory usage.
I've been experimenting with placing UICollectionView's in full page UICollectionViewCell's so as to take advantage of the reusability of UICollectionViews. The downside of this approach has been memory retention as the CollectionViews are never fully deallocated. Ive also heard that it is not the best practice to put a UICollectionView in a UICollectionView.
I've experimented with UIPageViewController's containing UIViewController's with the UICollectionView inside. This is more efficient as the UIViewController's can be deallocated as the user swipes back however as long as the user continues to select cells and create new view controllers the memory grows unbounded looking like a mountain.
As a bit of a hybrid I attempted as well to put ViewControllers containing UICollectionView's on UICollectionViewCell's. This method seemed to work best but I had to deallocate the view controllers manually as the user swiped.
Are there any strategies or libraries anyone could recommend that would fit this problem. How can I keep the memory down. I understand I'll need some kind of reusable views.
Ive been looking into this Library so far thank you in advance for all of your advise
Parchment Library
I think I understand what you're saying. You have a UICollectionView that can drill down to another UICollectionView, leaving the first one and its backing data retained until you come back and pop it off. Drilling down further and further allocates more and more memory until you back out.
I'd keep things as simple as possible. Solutions like putting a UICollectionView inside UICollectionViewCells can cause your code to get unnecessarily complicated, resulting in new issues and code that's programmer-hostile. If the user experience that works best is a collection view UI that you can drill down into infinitely, then go with that paradigm.
Your issue is not with UICollectionViews, it's in managing your backing data's memory use. That could be done a few ways. It would help to know what kind of data you have that's so large, and what "large" means, but here are a few approaches that come to mind.
One idea would be to unload any large data when you go to the next screen. For example, if your datasource uses an array with a bunch of large images, clear them out when the next view is pushed. Reload the data when your view appears again, or do it lazily when the view's cells need it, whichever works best for you. This would be the easiest approach and probably take care of your memory concerns.
A second approach would be to use one UICollectionView and use custom animations so it looks like a new collection view is pushing/popping from an old one, when in fact you're just changing the data for the collection view and reloading. You could even provide animations that are more interesting than pushing/popping.
On top of either of these approaches, you could implement the UICollectionView prefetch API calls to load data just before you need it. That will reduce your memory footprint even further.
All of these approaches assume that you can load the data to display from storage-- that it's not just in memory from recent webservice requests. Your users are guaranteed a miserable experience if your app has to keep requesting the same large data from the web over and over. So, if you don't have the data stored locally already, set up a cache.
Regardless of the approach, this is something you should be able to handle without adopting a library. UICollectionViews are designed to be memory friendly. Your issue is really in determining the best way to manage your backing data's memory use.
I am making modifications to an existing iPad application, and I'm having a hard time dealing with really messy scenes in storyboards. Almost every scene in the app consists of multiple views laid one on top of the other, each containing a different set of controls. Depending on the situation or data coming into the scene, some views are hidden, and others are shown.
It takes a LOT of time to decipher such scenes, and even when I figure out what changes I need to make it's terribly difficult to make those changes, and easy to screw up other things.
As an example, the following scene has 3 views that could appear (Start View, End View, Drawer History), depending on the situation, and they are all laid out on top of each other...
This seems like a terrible way to handle this, and I'm having a hard time believing this is standard practice, but I'm not finding much in the way of alternatives. I find very little in the way of questions where people are dealing with this problem, and the tutorials on how to design user interfaces seem to be too simplistic and never deal with scenes that are complex enough to run into this problem.
Unfortunately, this app is my primary introduction to doing user interfaces in iOS, so it has apparently become the default solution in my head. I've tried many tutorials, but they take a long time and don't seem to ever get to a situation that needs such a technique to solve it.
I would hope there would be a solution where each alternate view in the scene could be laid out on its own, and be made to appear within a placeholder view as needed.
What would be a more enlightened / more manageable approach?
That's what you'll get with Storyboards/Nibs/Xibs. I'm not saying coding your UI is better than using interface builder, but it is, at least for me. I believe, as far as I know, there's no other way to handle such multiple layers of views in one view controller in interface builder. I actually used to use interface builder before and that's how I add multiple layers of controls too. Sometimes some views are initially made hidden, but that would probably confused me or the other developer looking at the layout. Sometimes I extend the viewcontroller height to know that there's a view container with a constraint a thousand constant or a negative thousand constant to make it hidden and ready to animate when it's needed to be shown.
There are ways to somehow improve and organize your Storyboards. You can separate modules into different storyboard files; you can use references; avoid segues; and whatnot. It's still an individual or team's preferences.
Some ref:
https://cocoacasts.com/organizing-storyboards-with-storyboard-references
https://medium.com/#stasost/xcode-a-better-way-to-deal-with-storyboards-8b6a8b504c06
EDIT:
I'm thinking you could also layout separate view containers into a separate xibs, and then call them or layout them when needed. But that would add more files to your project.
I'm starting a new project and I have some doubts about storyboard good practices, specifically about optional hidden views (show only under certain circumstances).
Let's say you have an pdf downloader app, when the user select a download button a UIProgress bar appears and show the download progress. Should this progress bar be included in the storyboard or generated programmatically when the user press the download button?
It's a simple example but what about if there isn't only a UIProgressBar but also multiple hidden (optional) buttons? What if some of the buttons are overlapped? (I know overlapped button is bad design but just for the purpose of exemplify)
Should this ones be hidden or added programmatically? What about performance? Some say it takes more time to parse a Storyboard/Xib than a programmatically build view.
In DonaldKnuth's paper "Structured Programming With GoTo Statements", he wrote: "Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%."
So, you are trying to solve a performance problem you do not really have (at the moment).
You decision to have a view permanently or temporarily should be based on context of the view usage, not some hearsay performance issues between xib/stb vs programmatic approach, that resembles platform-wars, but otherwise, given how LLVM compiler works today, and what the HW performance of iPhone 4 or higher is, is basically nonsense.
Here's a simple rule. Have all the views in IB, hide or unhide them as necessary, and add/remove a view programatically only if you can give a good reason why.
I understand you instinctive desire to make it right, so instead of trying to manage one milion views in one controller, take a look at the problem that is satirically called Massive View Controller.
Proper decomposition into custom views, separation of concerns, clearly defined responsibilities split into more view controllers, view controller containment, is the answer to to address your concerns.
You want your app first and foremost to work correctly.That you can achieve by having a sound architecture so that you will be able to stay in control. Users will not appreciate that you instantiated some button programatically, because they couldn't care less. But if the app has inconsistent state because your view controller has 7000 lines and is spaghetti hell or is crashing, that is a problem.
if you are planning to use storyboards; would suggest to have view/buttons etc included . you can always hide / unhide the same from the code.
have a thought process and not cluster your view. Have multiple views and make your app look neat
So I have an existing app I'm working on for a friend...
and let's say I double click on animals_real and I get this screen...
Basically all I want to do is create a back button back to the home page on the animals_real page and all the other ones like it(body_parts_real, cleaning_real, etc.) but for whatever reason I can't find the xib file or the code for it and I'm not entirely sure what file it would be in. Also, since I am fairly new I'm not entirely sure how to implement the back button. Any help is greatly appreciated.
----------------------------------EDIT 1------------------------------------------
The main page works under ViewControllerForIphone.xib and the settings page is under SettingViewControllerIphone.xib. This led me to believe that the other pages would be under the SubPECSViewController_iPhone.xib. However, if I go in and edit that it doesn't change anything when I run the simulator. So, basically I have been trying to understand UIScrollView better and how it works but I am kind of just stuck.
Welcome to iOS. Other commenters will point out that you should start here at the UICollectionViewDelegate Reference (which you can also get to through Xcode (shift+command+0)
Basically, a uicollection view populates itself based on some array of data.Look here to see what's going on
(void)insertItemsAtIndexPaths:(NSArray *)indexPaths
When you tap on animals, this method is called:
– collectionView:didSelectItemAtIndexPath:
Some logic happens here, and I'm presuming you load the collectionview from yet another array.
To solve your original problem of a "back button," you might simply want to reload the viewcontroller's original datasource or possibly "pop" back up the navigation stack. Again, without seeing at least part of the code, there's very little we can do except speculate :)
Im trying to do app with a card based ui, kind of like Jelly. I was wondering the how this would be done. Im thinking by using a collection view but Im not sure. Are there any open source libraries that would make it easier to do this? Thanks.
You're probably not going to be able to accomplish this using out-of-the-box components. I don't think UICollectionView is going to get you very far. You will almost certainly need to roll your own.
I would start by creating a View Controller class for the "cards", instantiate a few of them, add the views as subviews to the main view, and get to the point where you can comfortably push these cards around with your fingers. You will want to read up on animating UIViews, and UIGestureRecognizers. Make sure the momentum is right. Apps like this really really demand highly-tuned physics, otherwise they'll feel awkward.
Once you get to the point where your cards are happily zipping around the screen, it's just a matter of getting them to "sink" into a couple pre-defined positions (focused front-and-center, and resting in a stack down below). You would probably also want to give your view controllers some sort of state that indicates whether they're "active", or not.
Easier said than done, obviously.