I have a UITableViewController that has the ability to save each row to a plist file. Currently when you press a detail disclosure indicator on the row it opens a separate UITableViewController with four static cells in two groups.
At the moment the data in these cells is just being saved in NSUserDefaults, but I'd like to be able to save them in a more robust manner (i.e. plist) and have each set of settings associated with its own row in the first table view controller.
Any help would be greatly appreciated.
Thanks,
Chris
Each of your groups can be saved as an array of dictionaries within your property list. Within each dictionary (or group), you may include various elements, least of which could be an array which would represent your 'related' items. This array could be a collection of simple values or even dictionaries themselves if you are working with a more complex set of data.
You may even take it a step further and use CoreData to create a nice relational object model.
Resources:
Property List Programming Guide
Core Data Programming Guide
Related
I have a UITableView which I populate by a list of objects I'm getting from a Realm database. What I want to do is to create sections and group items in the list by a property value in runtime.
All of the examples of grouping items in UITableView I see online are operating with it a prearranged dictionaries.
Is it possible to do?
You can set up your table view data source any way you want. You could write code that decides on the fly which items belong in which sections, but I would advise against it.
I would suggest setting up a method that takes your list of Realm objects as input, and builds an array of sections containing sub-arrays of the rows. Then your cellForRowAtIndexPath method can simply index into your model data like normal.
I want to loop through a TableView and extract the text from all the selected rows. I suppose I "could" create and maintain a special array that is updated every time a row is selected/deselected using the didSelect/didDeselectRowAtIndexPath methods. But creating a separate array seems like an extra step. Is there no way to let the TableView itself serve as the array and then simply loop through it and get the selected rows? What would the code look like? I'm new to Swift, so this might be a silly question.
Part of the problem is that cells are supposed to be reused, and when used this way it is not possible to loop through them all. You could get around this by using a unique reuse identifier for each cell, such as the indexPath itself or some underlying unique id in your model. Then, you could indeed loop through all cells and retrieve whatever state you desired from each.
You would, however, find your application crushed under the weight of too many cells being instantiated and kept in memory. If you don't have many cells you won't be killed, but try it with a big data set and your app will enjoy a very quick death.
It is far more efficient to store one array with a bunch of id's than a large number of memory-intensive UITableViewCells.
As mentioned in comments, you should work with underlying datasource, not the table itself.
For example if your table shows rows from Array, it is way more faster to retrieve strings directly from that array than creating UITableViewCells and get strings from them.
Get indices of selected rows using UITableView's property indexPathsForSelectedRows.
Query datasource for each row.
As has been said the tableview only handles displaying, your datasource is what powers the data shown if you think about it.
Plus as said before the tableview dequeues cells as they scroll on and off the screen.
The best way to achieve what you want is to add a property to your datasource for each element that will allow you to filter out the select properties easily.
How are you storing the state for each selected cell currently? As this is the same functionally you would use to be able to generate your selected text array.
I have an array of users
var selectedUsers = [User]()
users are added to this array as they are selected in a UITableView (see screenshot: https://www.dropbox.com/s/uk03mhgi3x4jesy/File%2006-10-2015%2C%2018%2003%2044.png?dl=0)
What I'm having difficulty with is when I press back and then reload the view controller, all the checkmarks disappear.
Is there anyway I can keep track of the selected cells?
Thanks in advance
You could use a delegate to pass a array between the two viewcontrollers. For example, each time you select a row, you can store the userId's associated with the row, in the array. So if you were to press back and then open the view with the UITableView, before you load the UITableView, you can first check if there is an array being passed to the viewcontroller containing the UITableView / if there is an array, check if the count is greater than 0. If the array is not empty, then use a for loop to cycle through the array of users being displayed with the array being passed containing all of the previously selected id's, then add the check marks that match up to the Id's in the array.
Here is a tutorial that possesses a similar example: http://makeapppie.com/2014/08/04/the-swift-swift-tutorial-why-do-we-need-delegates/
The answer to this question is kinda dependent on what you want the application to do... Do you want the User selections to persist even if the app is closed? If so consider using NSUserDefaults or CoreData. Otherwise store the data somewhere that does not get blown away (maybe the root view controller of your application). You could for instance implement the delegate pattern on the view controller with the table view and pass the values to the container view controller.. Just some ideas.
So you can use class NSUserDefaults to save small amount of data. If you want to have persistent store so you have to use Core Data that helps you store you data with scheme you provide.
If you just want to pass data from one view controller to another view controller so you just need use delegation pattern or you can use method prepareForSegue where you can pass some data as well but you can't store this way, just pass.
If you make your question more detailed you will get more explicit answer.
I am suffering to find a way to create a table view variable holder that is able to hold the section and the data from that section, I told I had find a good way using the this structure
NSMutableDictionary[key,NSMutableArray[myClass]]
It work very well as far as I don't need to update the data in the class 'myClass' it hold all the sections in a dictionary and all the members of the section in the array however it has been impossible to delete or change the data from the array.
So my question is, what is the best practices to create a variable that hold details from a table view with sections?
I am using swift and XCode6
I am trying to back my UICollectionView's data source with a data structure that (for good reasons) is more than two layers deep. In other words, my data can be broken into sections, but not all of those sections simply contain items. Some contain arrays of items (or "nested sections", so to speak). These items can be easily be referenced with an index path three indices long (3.2.4, for instance), but UICollectionView's data source methods only seem to support index paths up to two indices long.
All of the UICollectionView APIs use NSIndexPaths to reference collection view items, so in theory they should work with any number of indices. The challenge is getting the collection view to "know" to ask for cells, layout attributes, etc. for items at these deeper indices when the data source protocol only provides collectionView:numberOfItemsInSection: and
numberOfSectionsInCollectionView: to specify the indices it needs to ask for.
Is there any way around this that doesn't require me to (a) subclass UICollectionView, which Apple explicitly discourages (second point under "Tips for Implementing Your Custom Layouts") or (b) flatten my data structure, which would be less than ideal, and which seems unnecessarily limited given the APIs UICollectionView already provides?
It doesn't make logical sense in the scheme of a standard collectionView (or tableView) to have a three tier index. I've seen some cool tableviews that have "expanding" cells that work in the same way you're describing. It's just that the object representing the expanding cell tells the table that it has multiple items available.
I can't understand how your collectionView is supposed to look as an end product. If you are encountering arrays at some index paths, what are you trying to represent? I don't want to inform your design but why not just show one item at that particular index, and when a user selects it, expand or show another view with those subsequent items?