how to manage a stack of UITableViews without a navigation controller - iphone

I am new to iPhone development, and I am working on modifications to an existing iPhone app. The high-level overview of the issue is this.
I have a button displaying a pop-up containing a UITableView.
I'd like to click on a menu item and display a second UITableView with sub-items, including a back option. If the user clicks back, they go the original UITableView. If the sub-item has additional sub-items underneath it, it should (when clicked) launch another UITableView with these options. There is also a back button as a menu item that will allow the user to navigate to the previous menu displayed.
The challenge here is that I am not using a navigation controller. the original developer only wants to add UITable Views to the stack, add transitions between them as you go from one menu to the other. Most of the tutorials I have seen and tried utilize a navigation controller and Interface Builder to associate the UITableViews.
Right now, I have an XML data source populating the menu, and when I click on a menu item, the titles change correctly, but still uses the same UITableView to display the options - this has consequences of course, as some of the sub-items may not fit on a screen.
any thoughts on how this can be done? I can post some code if necessary, although I think the general description should be able to ring a bell with one of you smart guys!

This can be done in numerous ways.
I haven't done this first one, but you can probably create a UINavigationController and set its view to the appropriate frame (inside the bubble) hide the navigation bar and set the action of your back button to pop the current view controller.
Another method is to have multiple tableviews on one controller, the delegate and datasource methods have the UITableView as an argument so you can distinguish them when setting the height of your rows, headers etc and when returning a UITableViewCell.
The way I've chosen to deal with such configurations is to have one UITableView and have only the datasource change. When you reload, insert, delete rows or reload the whole table, you can change anything you want depending on the current datasource level. The easiest none animated way is to reload the whole table.
a) If your "options" go off-screen height wise (you want fixed height) table change the - (CGFloat)tableview:(UITableView *)table heightForRowAtSection:(NSInteger)section return value
b) If your "options" go off-screen length wise either make your cell's default textLabel flexible: cell.textLabel.adjustsFontSizeToFitWidth = YES; cell.textLabel.minimumFontSize = 14; or have custom cells (lookup subclassing UITableViewCell, which is recommended) for each datasource level.
If you subclass TableViewCells remember to have different dequeue cell identifiers for each level, so the table doesn't provide you with another level's cell class.
For the "stack" of tableviews or datasources, you can have an NSMutableArray with addObject for push and removeLastObject for pop.
For animations, UITableViews can animate their rows/sections for 3. (see documentation for insert, delete, reload - Rows/Sections UITableView class reference), for 2. you can even have UIView (if not CoreAnimation as Grimless suggested) animations, that move the current tableview to the left (setFrame:) and the next tableview from the right (setFrame offscreen before animation and then in place in the beginAnimation-commitAnimation clause), but make sure you add the tableviews in a container view (the bubble interior) that clips its subviews.

Oi. This is gonna be a tough one. My suggestion would be to maintain your own stack implementation. Then, use CoreAnimation to add/remove UITableViews from your main view controller to get animated effects. So whenever the user clicks on an element in the current table view, the appropriate controller creates a new controller and table view, and then your custom navigation controller pushes the old one onto the stack, removes the old table view from the main view, sets the new controller as the current one, and adds the new table view to the main view. Kinda messy, but I think it will work.

Related

how to stop one subview covering another

I have two subviews that load. One is a tabbar thats inside a viewcontroller which gets loaded fairly early on and the second is a view that appears when a tab bar item is pressed.
however when this subview is added it loads over the tabbar subview.. is there a way to bring to front or something along those lines?
There is a whole plethora of methods to choose from...see the section Managing the View Hierarchy in the UIView docs

UISegmentedControl underneath UINavigationBar, WITHOUT scrolling

Ok so ive been at this problem from a day or so now, seems to be a fairly common problem amongst new iOS devs. However, ive search google, appledev, stack overflow etc.
However, ive had trouble finding the correct solution. No where has clear answers.
I need the segmented control to either change the tabledata source or show a new view entirely, either would be fine.
At the moment, i have a work around solution where i put the segmented control inside a tableheader, this would work fine, but i dont want the segmented control to scroll with the table cells.
Im trying to have it static and unscrollable, just like the Navigation bar.
Ive tried a few option in interface builder but neither of them work, either they dont show up or i get a crash because it couldnt find the table view.
Although, i do know it has something to do with putting a view inside a view?
If anyone has a spare moment to write a quick but detailed guide, i would be very thankful.
edit
Attempt 1:
in IB...
View
-> Tableview (tableview inside the parent view)
creates this error
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UITableViewController loadView] loaded the "EventsViewController" nib but didn't get a UITableView.'
First of all you will need a single controller which will contain the segmented control, table view and other elements which you want to add.
Since there is a single controller for your application, any change in the segmented control can be captured in it. Once you capture the event you can decide whether to reload the tableview by updating the tableview or load a new view.
This new view can also be loaded as a modal view or as a new view to a navigation control or as a subview to the current view. (the call is left to you).
The advantage will be the segmented control and table view will be part of a UIView and scrolling one will not scroll the segmented view out of sight. Other advantage will be the new view will be loaded on top of the current view. You can have delegate methods to handle the back press event on the new view. You can also get data from the new view to a single controller.
UIView
--- Segmented control(you can wrap this into a seperate UIView
--- UITableView (it can also be wrapped into a seperate uiview )
--- Other widgets
Now you can have a single view controller controlling the above Main UIView. Hope this helps you. I have used a similar approach in one of my apps.
What you can do is have a segmented control basically change the table data source. Basically, set the action hitting either segment as [myTableView reloadData];. Then, in your data source methods, put some if statements up. For example, under numberOfRowsInSection, say: if (mySegmentedControl.selectedSegmentIndex = 1) //2nd button, use this array. Get what I mean?
This way you can use one view controller to with basically two (really one) table.

UITabBar functionality without UITabBarController

I have this problem, I've got a navigation-based application, and on the one of the detail view i need to have UITabBar, which will display some UITableViews. Since apple documentation says "you should never add a tab bar controller to a navigation controller" it make quite a problem, i've found this sample: link text, it's working, but after picking one of the table view, the UITabBar disappears.
don't use a tab bar controller, just use a UITabBar inside your controller view and manage the switches between UITableViews yourself, either by:
loading up as many table views as you
need and stacking them (bringing the
one corresponding to the tab bar hit
to front)
switching a single table view's data
source and delegate among a few
helper objects - one per tab in your
bar. When the user clicks a tab, reset the single table view's data source then instruct it to reloadData
Now that you are not using a TabBarController for showing the tableviews (as mentioned in the link), have you made sure that the table views or any other views you are adding when a tab is tapped are correct size?
You are adding a subview or bringing it to top so the table view is probably covering your tab bar.
When they are choosing an item from your table view are you pushing a new view controller onto your navigation controller? If so, you will leave the tab bar behind!
Without some hefty hacking, you generally can't do what you're trying to do. What you'd have to do instead is to deal with adding new views yourself when a table cell is selected so the new views you add don't overlap the tab bar at the bottom. Though this will probably break the navigation controller.
Though my advice is to rethink that part of the app's ui so you don't care that the tab bar vanishes. Sorry :(

Best way to handle multiple UITableViews in one UIViewController?

I have a UIViewController that should be capable of displaying tableViews with multiple data sources. The UITableView spans about half the size of the screen, and there is and up and down button that allows you to go through different data. Everytime the up and down button is hit, I'd like to ultimately use UIViewAnimationTransitionCurlDown or something similar to display the next UITableView.
The question is: do I need multiple UIViewControllers to do this, with a tableView embedded in each one? Should I just create one instance of UITableView and change its data source when an up or down button is hit? If it's only one instance of UITableView, how do I manage to get a curl transition over the portion of the screen it takes up to make it look like a new tableView is coming in?
Why not have each table view belong to its own UITableViewController, and nest these within the current screen's view controller? This way the screen's view controller is responsible for swapping out its subviews, each of which have a table view controller containing the necessary logic to show their data.
In the end, it comes down to what your functionality and data sets look like. It may end up being easier to implement the table view datasource & delegate code once, injecting an actual data source into this class - or it may be easier to write custom datasource code for each table view.

Having UITableView edit button outside of the navigation bar

I have a UIViewController, and within that view i have UITableView added in IB
The UITableView displays the items from my array beautifully
I would like to be able to edit the items i.e delete them
BUT The UITableView does not have a navigation bar, and i am not using a navigation controller within this app i am just adding and removing views manually.
What i would like to do is place an "edit" button somewhere else within the view ... is this possible? and how might i go about this?
Put a button somewhere. In an action connected to it set TableView's editing property to YES - it should work fine. You also need to implement delegate's editingStyleForRowAtIndexPath method (return UITableViewCellEditingStyleDelete to allow to delete cells).
You could make one special cell (e.g. 1st row, 1st group) a button by implementing a adaequate didSelectRowAtIndexPath.
Or you could put buttons for editing/deleting in each cell (if single deletion/editing makes sense).
Or you could place the UIIableView on a super view wich also contains the button(s) as sub views.