How do I create a UIViewController programmatically? - iphone

I am working in a app where i have data in UITableView. It is like a drill down application. User will click on a row and will go to next page showing more records in a UITableView. But problem in my case is that i dont know upto how many level user can drill. The number of levels are not fixed. So now i am thinking to create and add the viewcontrollers programmatically. Is it possible?? if yes how?
thanks in advance.

UIViewController *controller = [[UIViewController alloc] init];
controller.view = whateverViewYouHave;
Do you have your own view controller that you coded? In that case you probably don't need to set the view property as it has been set in IB if that is what you used. When you have your controller you can push it onto the navigationController or view it modally etc.

UIViewControllers are always created programmatically. It sounds like you just need to have the same class for each level of view controller, e.g.:
//CoolViewController:UITableViewController
//CoolViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (!self.isAtTopLevel) {
CoolViewController *cvc = [[CoolViewController alloc] initWithRecord:[self.records objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:cvc animated:YES];
[cvc release];
} else {
//do something else
}
}
In this case, thingies would be some sort of recursive NSArray (i.e. an array of arrays).

Related

Blank detail view pushed from a TableView that was created programmatically

My setup is using a storyboard in which I create a login, then a home screen in which the user can press a button to display their messages.
These are displayed in a table which is instantiated programmatically.
From this table I then want to press a row to go into detail about that row, but when i do this the view displayed is blank but all methods associated with the class are being fired (view did load, and so on).
I have literally tried 10 different ways from different solutions others had had suggested on their questions but nothing works.
Code to make new view and push it:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
messageDetail *messageDetailView = [[messageDetail alloc]initWithNibName:nil bundle:nil];
messageDetailView.message = [entityObjects objectAtIndex:indexPath.row];
[self.navigationController pushViewController:messageDetailView animated:YES];
}
ViewDidLoad of DetailView:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(#"Message Detail:\n%#",message);
messageTitle.text = message.message_title;
messageBody.text = message.message_xml;
}
I have tried using a segueIdentifier route and then intercepting the prepareSegue: to add data to the new view, but as the tableView is created programmatically there is no segue.
I have tried instantiating the view from storyboard via:
messageDetailView = [self.storyboard instantiateViewControllerWithIdentifier:#"MDV"];
But the app crashes as there is no view with identifier, even though i set the identifiers.
You send nil as nib name, if you do not have a nib file do not allocate the message detail view with initWithNibName function.
Use raw init or initWithFrame. Whichever works for you.
Good luck
I basically did the same thing with this code here. Hope this helps
Detail_View *next=[[Detail_View alloc] initWithNibName:#"Detail_View" bundle:nil];
//These are just values that I needed to set before going to the next page.
//You can use this if you want to pass over the value of your table row
//otherwise ignore this
next.htmlContents= [[storage_array objectAtIndex:indexPath.row]objectForKey:#"title"];
next.titleText=[[storage_array objectAtIndex:indexPath.row] objectForKey:#"title"];
[self.navigationController pushViewController:next animated:YES];

iPhone creating nested views

I'm noob in iPhone programming.
I want to create navigation-based application with several nested views, when first and second are UITableView-type, and the third is simple UIView with my own interface, which I built in Interface builder.
When I run the App, touch the row on the first table-view I transfer to the second, and when I touch the row on the second, I transfer to the third, but on the third View I don't see my interface, which I built in Interface Builder, just blank screen.
This is part of my code, where I try to call my third view:
if(self.reportView == nil){
ReportTypeViewController *viewController =
[[ReportTypeViewController alloc] initWithNibName:#"ReportTypeViewController"
bundle:[NSBundle mainBundle]];
self.reportView = viewController;
[viewController release];
}
[self.navigationController pushViewController:self.reportView animated:YES];
self.reportView.title = #"Reports";
That's OK, guys.
I've just didn't add text to my button, that lies on my view, that's why it was blank.
You don't need [NSBundle mainBundle];
it should look like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ReportViewController *vc = [[ReportViewController alloc] initWithNibName:ReportViewController bundle:nil];
vc.title = #"Reports";
[self.navigationController pushViewController:vc animated:YES];
[vc release];
}
If you just create the view on demand with the selection it's much easier.
In IB, make sure you remembered to set the Class of File's Owner to ReportTypeViewController, and make sure that the view outlet of File's Owner is connected to your view.
Does ReportTypeViewController really inherit from UIViewController, or is it a UIView, as you say you built in IB?
navigationController pushViewContoller:animated: needs a UIViewController not a UIView. In IB, you can add a UIViewController and move your UIView onto it, or create it programmatically.

iphone UITableVIew (Navigation-based )

I'm working on a navigation-based application.
My rootViewController contains 3 cells
-When the first one is pressed a UIViewController is pushed (THIS WORKS)
-The problem is with the 2nd and 3rd cells that are supposed to push a UITableViewController
The app is running with no errors and it is NOT crashing at all, but when i navigate to the tableview, an empty table is viewed with no elements in it.
Is the problem with this part of the code?? :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *detailViewController = [[UIViewController alloc] initWithNibName:#"Introduction" bundle:nil];
detailViewController.title=#"Introduction";
UITableViewController *myPictures = [[UITableViewController alloc] initWithNibName:#"Pictures" bundle:nil];
myPictures.title=#"Pictures";
UITableViewController *myImages = [[UITableViewController alloc] initWithNibName:#"ImagesViewController" bundle:nil];
myImages.title=#"Images";
// Pass the selected object to the new view controller.
if (0 == indexPath.row)
[self.navigationController pushViewController:detailViewController animated:YES];
if (1== indexPath.row)
[self.navigationController pushViewController:myPictures animated:YES];
if (2== indexPath.row)
[self.navigationController pushViewController:myImages animated:YES];
[detailViewController release];
[myPictures release];
[myImages release];
What you're doing it very wrong (apart from your original problem). Why are you instantiating each view controller and then only using the one based on the current 'cell selection'? This will slow your app down depending on how much time it would take to load each of these separate views. You should only instantiate the relevant view controller inside the "if (indexPath.row == 2) {" block.
Apart from that there are many things wrong about your approach. What you are doing will never work since instantiating a generic UITableViewController (even if you supply your own nib) will obviously only show you an empty view. You need to have a class of your own which the nib is tied to as a delegate which will then supply the TableView with data.
I believe when you created these nib files (for example "Pictures") xcode also give you a 'PicturesViewController.h and PicturesViewController.m" files? If so, you need to write the appropriate code there and ensure the Tableview in the "Pictures" nib file has its 'datasource' and 'delegate' set to 'PicturesViewController'. Then when you want to show that view do this instead:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 1) {
...
} else if (indexPath.row == 2) {
PicturesViewController *myPictures = [[PicturesViewController alloc] initWithNibName:#"Pictures" bundle:nil];
[self.navigationController pushViewController:myPictures animated:YES];
[myPictures release];
}
}

Code is exectuting but the view is not loading when called form a function?

I am doing a book kinda application using a viewBased application. The mainView acts as the backgroundView for loading pages. Each page is a different view and have its own nib. When i swipe on a page(actually on the mainView which have loaded the current view/page), that page will be removed and the next/previous page will be added.
[currentPage.view removeFromSuperview];
[self.view insertSubview:nextPage.view atIndex:0];
I have added a popoverController with a barbutton in this mainView. Its intialized with a tableviewController class named popClass. PopClass is another UITableViewController class which will act as the parent for the popViewController.
self.myPopController = [[PopController alloc] initWithStyle:UITableViewStylePlain];
self.myPopOverController = [[UIPopoverController alloc] initWithContentViewController:myPopController];
When I select certain row in the popover, I want the backgroundview(mainView) to load the page corresponding to the number of the row.
For that I have written a function in bookView(mainView) Controller class. And is calling it from the popOver's parent class when i select certain row.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger toPageNumber = indexPath.row + 1;
[viewController changeToPage:toPageNumber];
}
Function and the lines of code are executing but nothing is happening. Even the log lines are printed but no action takes place. The code is the same for removing a page and adding another page which is working successfully when i swipe the view/page.
What is the problem? OR is there anyother way to make the view change in mainView by using the popover?
You need to have refernce of the background view controller in the popover controller.
In the PopController controller you should have a delagate like:
#interface PopController: UITablViewController{
//// other varibales;
id delegate;
}
#property (nonatomic, retain) id delgate;
Now from the class in which you are showing the popovercontroller
you should add this line:
[myPopController setDelegate:self];
Then you can easily acces any method of the main view controller class. By using
[delegate callTheRequiredMethod];
Hope this helps.
Thanks,
Madhup
It's hard to tell what's going wrong without looking at the code. That said, here's what I'd do:
(1) When a row is selected in mainView, present the popoverController modally:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PopoverViewController *vc = [[PopoverViewController alloc] init];
[self.navigationController presentModalViewController:vc animated:YES];
[vc release];
}
(2) When something changes in the popoverController, for example a row is selected, set a value in the parentViewController (which should be the MainView):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.parentViewController.value = someValue;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
(3) Dismiss the popoverController where-ever you choose by calling:
[self dismissModalViewControllerAnimated:YES]`

UITableView with multiple viewcontollers

I just filled my UITableView with Planets. I would like each cell clicked to open into a new Xib (if this sounds like the wrong approach please direct). I can get a secondviewcontroller working, its getting the thirdviewcontroller and fourthviewcontroller working? Thanks.
Place your main view controller (the one with the table) inside a UINavigationController. Then, when the user selects a row, push a new view controller onto it.
The following function will help. As Ben Gottlieb said your main view controller will need to be in a UINavigationController. You need to implement the delegate method for didSelectRowAtIndexPath and this is where you create the new controller for your new view and load it.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
YourViewController *controller = [[YourViewController alloc] initWithNibName:#"YourViewController"bundle:nil];
[[self navigationController] pushViewController:yourViewController animated:YES];
[yourViewController release]; // don't leak memory
}
Based on the row number you can decide which nib to load.