In my app I have a detail screen for Product objects. The UI calls for the product details to be displayed using a grouped table view type interface with 3 sections.
Some of the cells in this table are conditional. For instance, by default the third section should display a single cell that says "Register Product" and should push the registration view when tapped. If the product is already registered then the third section should instead display two cells one for Warranty and one for Servicing Information. These would each go to different screens when tapped. Also, they both need to display some kind of data on the table cell. The warranty cell says when the warranty expires and the Servicing cell says when the next servicing is due.
QUESTION (finnally): What's the best way to define the cells and sections that the table should have in any given situation. Primarily I'm looking for a maintainable way to do this since I already have some ideas about un-maintainable ways to do it.
Should I create some sort of keyed dictionary and add/remove items from it during viewWillAppear based on the Product being displayed? I'm worried the number Switch statements that I would have to use throughout the various tableView events to check what type of cell is at a given index path.
Any ideas?
Have a look at Matt Gallagher's Tableview Classes. They provide a simple and extensible framework for customizable Tableviews. Cells can be loaded from a NIB or constructed in code. There's a simple interface to provide the data for each cell (- (void)configureForData:(id)dataObject).
Populating the Tableview is easy:
[self addSectionAtIndex:0 withAnimation:UITableViewRowAnimationNone];
[self appendRowToSection:0
cellClass:[NibLoadedCell class]
cellData:#"This is row 0"
withAnimation:UITableViewRowAnimationLeft];
For persistent storage of the data I recommend to create a plist dictionary and load/save data from there. See Property List Programming Guide. For complex database structures use core data for storage.
Related
I'm trying to create a screen for entering patient information very similar to the contacts edit screen in iOS.
I think the screen should be a static table with cells for simple things like firstname, lastname, etc.
Within the static table would be cells containing embedded tables with dynamic cells. There would be an embedded table for phone numbers, another for street addresses, and another for medical providers, ... Each of these embedded tables could have zero or more entries.
Is embedding dynamic tables in a static table the right way to do this?
I don't know how to get the height of the embedded content so that I can set the height of the static cell.
This is quite an advanced topic that I cannot cover in depth now, but I will try to give you a few pointers on how to proceed.
I would advise against embedding tableviews into other tableviews.
Use a dynamic tableview.
Create a view model that provides an array of objects for the controller to render.
The controller only takes objects from the view model and decides which cells to render (no logic in the controller)
In the view model deal with all the complexities of the data (static content, dynamic sub-arrays, sections, if-else statements, ...)
Build the complex cells (address cell in your example) using for example stack views.
Dealing with multiple fields inside one cell can be tricky, you will have to do some more research on that topic.
There are many tutorials on view model architecture ("mvvm"), google it.
I hope that helps, good luck and happy hacking!
I'm completely new to swift and Xcode and everything regarding iOS development. I have a UITableView that populates UITableViewCells, I've been able to graps the fundamentals of that. But what if I wanted to add an extra cell at the bottom upon every visit?
I guess it's a mix of dynamic and static, but I can't find any answers whether this is case as of present date, since information in threads shows discrepancy.
You need to use dynamic table view. For example you have an array with some elements and your table view is displaying them. If you want to add a cell on the bottom, simply add another element to your array and then call self.tableView.reloadData()
I am implementing real-time searching of a UITableView. I would like to display the results in a separate table view (in it's own UITableViewController class). Is there a way to simply replace one tableview with another once the user begins typing in the search bar?
Refer to UISearchDisplayController. It will surely provide what you require :)
Create two tableViews, tableList and tableSearchResults. Also declare one more tableView namely, tableCurrent. Initially make tableCurrent to point to tableList, then load the objects into tableCurrent. You can use this (tableCurrent) to display contents and handle selection events.When user fishes searching, assign tableCurrent to tableSearchResults, and then load objects from search results array. This will make two table views, one for Listing and other for search reasults...
Happy programming
There is little reason to use two actual tableViews, if only one is visible at a time. You could just change the .dataSource and .delegate properties. (If they are sized and styled the same anyway.)
I am trying to animate the reloading of a table view. Currently, I download the array of table view items and if the user reloads the table view manually, it downloads into a separate array, compares the current to the newly downloaded, and if they are different, it reloads the table view with the newly downloaded array. Is there an easy way to, somehow, compare the arrays and insert/delete rows (animated, of course) accordingly?
I found the Apple's Table View Programming Guide to be very useful for this question:
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/TableView_iPhone/ManageInsertDeleteRow/ManageInsertDeleteRow.html
If you are using arrays, you would need to deal with figuring out inserted/deleted rows. If you are dealing with a larget set of data, then you should consider using Core Data with NSFetchedResultsController. See documentation for NSFetchedResultsControllerDelegate for getting inserted/deleted rows.
Is there anything currently in the SDK that allows for re-ordering of tableView sections? As in, move the entire section below or above an adjacent section? This is plausible with individual UITableViewCells. Haven't seen it done for sections though.
Maybe not ideal but fairly simple so worth considering:
Add Up/Down buttons to your section headers. Down on the first, Up on the last and Up and Down on all the others. Then respond to the button presses by programmatically re-ordering the table. Up moves the section up one and Down moves the section down one.
Martin
There's no built-in touch-responsive API for moving table view sections - you'd have to do it programmatically then send a [tableView reloadData] message or similar.
It is concievable, though, that you create a table view where each UITableViewCell's view is itself a UITableView containing a section of your data, so that the cells in the "master" table are draggable as UITableViewCells. This would let you reorder "sections" in your table, but they wouldn't be sections anymore - they'd be separate tables, each with a single section.
Maybe as an alternative idea, reloadData on the table to only show the sections as a kind of "collapsed all" view on your table (maybe it is possible to even animate this?) which then has one section, containing all sections as row elements. The only extra required would then be a button that will set your table to this state.
I tried to move rows from one section to another, while updating the datasource of course. But this seemed to be mission impossible. Empty cells in between, wrong contents in sections, wrong ordering of sections were the only results I got.