Injecting table cell at end of table - swift

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()

Related

How does 'conditional rendering' work in Swift / Xcode?

In React and other web front-end frameworks, there is the concept of 'conditional rendering'. You render certain elements of the UI to the DOM based on certain conditions being true or not.
How does the concept of conditional rendering work in Xcode / Swift? Since you apparently build the UI on the storyboard, I don't know how to conditionally render elements.
A specific example: Let's say I've got an array of arrays and for each array in the array I want to render a tableview. How would I approach this problem?
Short answer: "It doesn't." That's not how iOS works.
Edit:
You can certainly write code that builds your UI from code, and if you do that, you're free to use conditional logic to decide what elements to add to your UI.
In fact, SwiftUI uses code to build a UI, and is a reactive style development platform. You should look into that.
A UITableView, as in your example, is a data-driven UI element. It uses a data source to decide what cells to display. Depending on the types of entries in the data source, it might create different types of cells. That is similar to what you describe.
It doesn't really make sense to have multiple table views on screen at once, so I'm not sure what "...for each array in the array I want to render a tableview" would look like.
I guess you could write a view controller that had a scroll view as it's content view, and when it loaded, it took your array of arrays, and used the outer-most array to decide how many instances of table views (or table view controllers, better yet) to instantiate. It would create table views/table view controllers in a loop, and install their views into the scroll view, keeping track of the geometry. Altnernately, you could put the table views in a stack view, and put the stack view into a scroll view.
However, the UX would be awkward. The user would need to drag up and down inside each table view to navigate inside it, and also drag up and down on the scroll view in order to move between table views.
Let's say I've got an array of arrays and for each array in the array I want to render a tableview. How would I approach this problem?
You would write code—presumably, Swift code, since you used the swift tag.
Let's make it even more concrete. You have a Bookcase object which has an array of Shelf, and each Shelf has an array of Book.
If you're using a storyboard, you can have a ShelfController scene in your storyboard with a single table view to display the Books in one Shelf. You can also have a BookcaseController scene with (let's say) a stack view. The stack view has no subviews because you don't know, when designing the storyboard, how many shelves you'll need to display.
Then, in Swift code, when BookcaseController is given its Bookcase model object, the BookcaseController instantiates the ShelfController scene once for each Shelf in the Bookcase. It adds each ShelfController as a child view controller, and adds each ShelfController's view (a table view) as an arranged subview of its (the BookcaseController's) stack view.
Let's say I've got an array of arrays and for each array in the array I want to render a tableview. How would I approach this problem?
You'd probably display a list of all the arrays (or whatever each array corresponds to) and a table. When the user selected one of the things in the list, you could then set the table view's data source to use the corresponding array.
That's not the only way, of course. If you really want to draw different tables for each array in the list, you can do that — you're in charge of your code. But why make things more complicated?
Since you apparently build the UI on the storyboard, I don't know how to conditionally render elements.
Storyboards aren't the only way to build a UI, and they're also a lot more flexible than just a static collection of elements. A storyboard is essentially a collection of connected scenes, where each scene is a template for a screenful of content. But your code can adjust the objects in a scene, including hiding or showing them, changing their position, and adding ore removing views. So if you want you could have a scene with a different table for each of the items in your list, and then just adjust the visibility of the various tables according to whatever thing is selected. Or you could have no tables at all, and your code could create one on the fly and insert it into the view.
In short: you're assuming too much about how storyboards work. Start reading about how view controllers work and you'll soon have a much better understanding of the kind of control you have over the UI.

UITableView display search results in separate tableview

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.)

Animating TableView Instead of Plain Reloading

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.

How do I make an editable detail view on the iPhone with a grouped UITableView?

I want to make a grouped TableView similar to the Apple iPhone contacts application.
I need a lot of standard fields which can be edited, but I would only like them editable once the edit button in the navbar is clicked.
This has been bothering me forever that I could not find a good tutorial.
Thanks in advance.
This is not easy. I just built the same thing because there is nothing available from Apple. I ended up creating a single table cell with a UILabel and a UIView on it. The UILabel is for when the cell is in read mode, and the UIView is for editing. The UIView contains a number of UITextFields. These are the individual fields. I also had to implement drawing code to draw the lines between the fields. Then I had to come up with the code to pass in an address object, load it into the fields, format the text for the label, switch in and out of editing mode (with animation), and finally handling saving of changes and canceling. As yet it doesn't handle tapping the address type to select that from a popup list, but I have most of the code in place for the rest.
This could have been done using individual table view cells for each field. But then you can't select the whole thing the way it does in contacts and adding and deleting addresses becomes trickier.

Three20 TTSectionedDataSource row height

I'm using Three20 to create a table with several textfields for user registration. I've found two possible methods using Three20. The first uses the TTSectionedDataSource's tableDidLoadModel method to manually add UI components and the second adds custom items that contains pre formatted UI components. The second option seems way more complex and I'm having a difficult time accessing the individual fields. So if one field is a textfield for the username, I need to access the field to submit the username and it doesn't seem like there's an easy answer. The first option gives me a lot of flexibility, but I can't figure out how to set the individual row heights. One row may have a label above a text field, another may have an image, etc. Is there a method that can be used in TTSectionedDataSource that will allow me to set the height for each row? Thus far, I'm using method one and creating UIViews to hold a label field and a text field. I've tried changing the frame of the uiview before it is added to the items array, but it has no affect.
Any ideas?
I believe I may have figured it out. Not sure if this is the correct solution, but it seems to be working.
First in my custom item class I pass the datasource as a delegate. Now that the delegate is part of the item, I can pass it to my textfield as the delegate. As long as I include UITextFieldDelegate in my data source class, it will respond as the delegate to my textfield. So that's getting the content from the textfield.
If I want to change the content in a textfield from the datasource, I can leverage the method:
- (void)tableView:(UITableView*)tableView cell:(UITableViewCell*)cell willAppearAtIndexPath:(NSIndexPath*)indexPath
I can check the row using indexPath.row then type the cell as the corresponding custom cell class. From there I can access any public methods in my cell class. So I created one that returns a reference to the textfield. So I can say:
[[(MyCustomTextFieldCell *)cell theTextField] setText:#"hello world"];
Next step is to assign it to a local ivar and then I'm assuming I should be able to access it at any time.
The main reason I want to be able to modify the content of the textfield is that in certain instances by clicking on the textfield, a picker will come up and the results of the picker are formatted and inserted back into the textfield.
Please let me know if my approach is too convoluted. Perhaps I'll create a sample and post it for everyone to rip apart and tell me I'm a moron and there's a better way.
thanks,
howie