Adding navigation controller to custom made table view - objective-c

I want my table to show up only half way from the bottom of the screen, the upper half meant for an image. To do this, I added a table view through code using CGRectMake specifying the (x,y) co-ordinates I wanted it to start at.
Now, I want each row of this table to navigate to a new view. How do I make the navigation controller push my new view? I tried to add a navigation controller to my main view, but that its helping any.
Please advise on the best way to do this.

Check out the UITableView Class Reference, specifically the methods under the header Managing Selections:
The method you most likely want is – selectRowAtIndexPath:animated:scrollPosition:. You can push a view controller onto the stack from this method based on the selected row. To push onto the stack, you will need to set up the UINavigationController, then call
[self.navigationController pushViewController:viewController animated:YES];
Apple has a nice tutorial on this topic, complete with many examples.

Related

Determine if viewcontroller is already on stack and if so, go to or dismiss it

I have an app I am working on that has a main screen with two buttons. One will take you to a view of a GPS (map) and then once there (new VC) it has options for setting that position or bringing up a list (tableview, another VC) of all locations already tagged.
At the list VC, if you click on the table cell, it will bring up the VC with the map. Problem is, this then adds the same VC bak on the stack. If a user clicks the Cancel button, they go back ones screen, then cancel goes back another screen, etc... until back to the main.
I know I can do the [self.navigationController popToRootViewControllerAnimated:YES]; to pop back to root but that is not always what I want.
Also, I know I can do: [[[self presentingViewController] presentingViewController] dismissModalViewControllerAnimated:YES];
I guess what I am saying is I want to "reuse" the GPS map view so I can call it from other VC's, so that is why I didn't go with the "pass back" to calling VC. So, is there away to either when a button is pressed and is to present a new VC, can I dismiss the prior one after the new one is shown? This way, a dismiss of current VC would take me back to where I need to be.
I hope makes sense and also that this question doesn't fall into the "Not an actual question" category.
Any help or better suggestions is greatly appreciated. Thx
Geo...
If you want to jump back some number of levels in a navigation controller's VC stack, you'll probably want to use its popToViewController:animated: method. To figure out if a particular view controller is on that stack, look at the navigation controller's viewControllers property. Be careful, though, as this kind of jumping around is a rather nonstandard UI behavior (even though there's API for it) which might confuse your users.
Also, using navigation controllers and presenting modally aren't the only ways to manage multiple view controllers -- you can always set the window's rootViewController yourself (and animate the change with UIView animations), even wrapping up your custom transition type in a custom UIStoryboardSegue if you like.
You can put a delegate in the table view. So that when a cell is pressed the info is passed to the delegate method in the VC which will dismiss the table view and reloads itself with the new info. You will have to implement refresh method in that VC.

How to Create UITabController on a Button Click

I am working on app. It has normal 3 views. On third view, I have a table view. If I select any row, I want a view which contains UITabController. I have created a simple UITabController app, but unable to do this. How to do this ?
thanks in advance
IMHO, your question is perhaps ill conceived.
A tab bar controller controls view controllers which in turn control views. Your suggestion that a view contains a controller of controller simply does not make sense.
Maybe what you really want on selecting a row in your table view is to present a new view controller and then make the (existing) tab bar visible.
You usually want a UITabBar to be THE navigation for your application and not show it later on one view.
But if you want to do so you should show, as Mundi said, a new UITabBarViewController when you select your UITableViewCell.
I don't know your exact usecase, but if you work with a UITableView I would use a UINavigationController to push a new View when you tap one UITableViewCell. Then it may be better (If you have 2-3 Elements) to use a UISegmentedControl in the UINavigationBar. This would look like this.

Increasing number of living Views

I've set up a really simple project using storyboards including two views as shown here: http://i.stack.imgur.com/iRx21.png. The navigation can be done by either selecting a cell in the custom table view or hitting the back button labelled with "<<". Everything works fine except the following:
when I switch between the views, every time an instantiation happens. The profiling shows an increasing number of view objects. I would like to keep only one of each view and instantiation should be happen only once. What am I doing wrong? (I'm using ARC.)
Thanks in advance!
You should not link your back button to the parent view controller. This is what causes the new instantiation.
The way to go is to embed the table view into UINavigationController (in IB, choose Editor -> Imbed In -> Navigation Controller. Then change your segue to a Push segue. You can of course hide the navigation bar etc. to make things look exactly as you like. Then, link the back button to the controller with an IBAction and in the handler do a simple
[self.navigationController popViewControllerAnimated:YES];
This would be the appropriate logic of what you are doing. Of course, you can also push the web view modally and then handle the button click with
[self dismissModalViewControllerAnimated:YES];

Re-use tableview from different controller: how to split didSelectRowAtIndexPath behaviour?

I'm currently working on my Favorites implementation. In the end, it should work the same as the favorites features in the Phone book on the iPhone.
I've the following set-up (besides other controllers and classes):
TabBarController (named mainTabBarController)
NavigationController with a Tableview (let's call it listNavController)
ViewController with some components for displaying row details (named detailViewController)
NavigationController with a TableView for favorite records (named favoritesNavController)
From the favoritesNavController, I want to select a row (from listNavController) so I can add a new entry to my Favorites tableview.
So, I decided to re-use my listNavController because it has all the functionality I need. Like searching, index, etc.
I've managed to show the listNavController from the mainTabBarController. So no problem here. When I select a row from the listNavController, it displays my detailViewController for that row. Of course, this was expected because that's in didSelectRowAtIndexPath in listNavController.
But, when I launch a listNavController from my favoritesNavController with the help of presentModelViewController, it still shows the detailViewController when selecting a row.
In this case, I want to return the selected row to my favoritesNavController. Then I can add it to my Favorite's list.
So, how do I differentiate this behaviour in code ? Should I use protocols, delegation, etc. ?
Any tips ?
With regards,
Rutger
It turned out that I was looking in the wrong direction.
The solution to the posted question is as follows:
I created a subclass of my listNavController and overrided the didSelectRowAtIndexPath method. Next I presented this new view controller with a navigation controller as a modal view (presentModalViewController).
Finally I set the delegate and a protocol for the subclassed view controller to the initiating class. This way I can present and dismiss the subclassed view controller from the same controller. A much more clean and MVC way to go!

How do I create a UINavigationController with a default "back" state?

I have a UINavigationController, complete with table view and associated magic.
The data I'm populating that table view from may have items from multiple categories, but the default view for the user will be one in which they are viewing all of the items, and then they have the ability to move backwards to a different table view that would allow them to select a different category, which would then return to the original table view with the appropriate data populated.
What's the proper approach for this? I can't seem to wrap my head around how I would make the navigation controller give me a back button (with appropriately wired up actions) without having come from a previous view in the stack (which wouldn't really exist at launch time if I start the user off from what is essentially the detail view, in stack terms.)
Also, the back button should be titled "Groups", not "Back", but that's really just an implementation detail. :)
Update: This issue finally manifested itself in production code, and here’s how I fixed it:
My UINavigationController is created in a nib, with the root view set as the “groups” view. Then, in my app delegate, I push the second view onto the stack while the app is launching.
That works fine for achieving the proper stack, but that doesn’t help with the back button title, because the navigation controller didn’t seem to want to grab the title from the root view, and instead was showing a back button with “Item” as the title.
So, on the pushed view, in viewDidLoad, I set:
self.navigationController.navigationBar.backItem.title = #"Groups";
and that did the trick.
The only potential downside of doing it this way would be if the pushed view controller were ever used in a scenario where the view below it wasn’t the groups view, but since the design of this particular application ensures that never happens, I’m accepting that failure. ;)
Another update:
I’m an idiot. Just set the title property of the navigationItem provided by the navigationController in Interface Builder, and boom, no issue. Or do it in code. It doesn’t matter, just don’t do it by setting the backItem.title way I show you above. That’s just dumb.
In your application delegate's .m file in the application:didFinishLaunchingWithOptions: method just push your view controllers like you normally would with[self.navigationController pushViewController:your_view_controller animated:YES]; and it should push them on before the application's first view controller appears.
To change the text of the button to Groups just call this before pushing your controllers.:
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"Groups" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
[newBackButton release];