I have a TableViewController (VC1) set to push-segue to another TableViewController (VC2). This connection was made in storyboard via ctrl-drag from VC1 to VC2. When the segue is performed, the app freezes and I see the CPU peg to 100% and memory usage start climbing rapidly. I started out with a custom VC2 and saw that viewWillAppear was called and the table delegate methods such as numberOfRowsInSection were being executed properly.
In an attempt to narrow down the problem I can see that even a vanilla UITableViewController (no custom controller class) as VC2 has the same problem. But when I set VC2 as just a vanilla UIViewController (not table), it segues fine.
I have about a dozen other TableView -> TableView segues elsewhere in my app that are set up the same way and no problems with them.
VC1 code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"myseguename" sender:self];
}
It turns out my problem was caused by trying to use appearance proxy to set the backgroundView of UITableView. Found in the docs (https://developer.apple.com/library/ios/documentation/uikit/reference/UIAppearance_Protocol/Reference/Reference.html) that UITableView backgroundView is not marked as UI_APPEARANCE_SELECTOR.
Related
Currently, I have a basic UI set up in Interface Builder that features a UITableViewController, with a seque leading from the prototype cell to a detail view. My code dequeues the cell with the identifier I have set in Interface Builder, but when testing the app, a tap on the cell does nothing but turn it blue.
I want the segue to push the detail view on to my navigation controller's stack, but the segue simply won't happen. Why could this be?
Assuming you are working on storyboards (segues, etc.) there is a bug in the auto layout scheme of iOS. Hence the segue is not fired. However, you can simply give the segue and identifier in attributes inspector of the segue, and programmatically from your class you can use
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
in this method you can fire the segue in the following manner.
[self performSegueWithIdentifier:(NSString*) target:(id)];
Let me know if this helps you.
(Make sure your delegates and datasources are all set up correctly).
This might look like a silly question to some, but handling the different types of controllers in an iPhone application is still a little fuzzy to me. Here's the setup:
I have a Tab Bar application with four tabs. Each tab passes control to its respective ViewController, where some of those are initialized with a .XIB file and some are done purely programmatically. One of the programmatic ones is DirectionsViewController, which is essentially a UITableViewController. Selecting a cell from its table needs to present (modally) a DetailedDirectionsViewController, which needs to have some sort of back-reference to the presenting view controller. I figured the easiest way to do this is to add a navigation controller to the Directions and DetailedDirections VCs - except I don't know how to do this without a .XIB file.
Also, the way I hand control over to DetailedDirections is by changing Directions the following way:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailedDirectionsViewController *vc = [[DetailedDirectionsViewController alloc] initWithStyle:UITableViewStyleGrouped];
[self.tabBarController presentModalViewController:vc animated:YES];
}
I seem to recall one of my professors saying that presentModalViewController is kind of an old method and there are better alternatives... I just can't remember them right now.
For what you want to do it would be best to have the tab in your tabbar manage a UINavigationController, and to set the rootViewController of that navigation controller to your DirectionsViewController.
Then in your direction view controller's didSelectRowAtIndexPath: methods you can do the following:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailedDirectionsViewController *vc = [[DetailedDirectionsViewController alloc] initWithStyle:UITableViewStyleGrouped];
[self.navigationController pushViewController:vc animated:YES];
}
And it will function like you want it to. The UINavigation controller will take care of putting a back button on your detailed directions view controller.
If I understood well, in the tableview:didSelectRow..: you just need to create a navigation controller initializing it with the view controller that you want to display modally, before presenting it create a UIBarButtonItem and add it to the navigation bar of the navigation controller as selector create a new method with the dismiss command inside.
I have a BaseController and three subclass ViewControllers. In each of the subclass ViewControllers, a query is made to the sqlite database to get the information. I want to add a longPress feature at the BaseController level to pop up a UIPopoverController.
So then I have a subclass of UITableViewController to be used with the UIPopoverController to display the data. Do I need to get the information from the sqlite database in my subclass of UITableViewController to have that information be displayed in UIPopoverController? It seems redundant since my 3 subclasses of the BaseController already have the data, and now I just want to have that data in a UIPopoverController, as well as add additional functionality like when a row is selected from the UIPopovercontroller.
The UIPopoverController is a view controller.
SO:
display the table.view in the UIPopoverController.
As far as adding functionality to a row press:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// in here write what happens. if its row specific write:
/// if (indexPath.row == ROWNUMBER){method} (rows start at 0)
}
and all of this goes in the .m file of the tableView you are presenting
This "wizard" gives me a tableview to work with when I build and run. RootViewController is subclassing UITableViewController. Opening up the XIB, there is a table view, but what is the name of the tableview instance being displayed?
I'm trying to reload the tableview after a receiving data from an asynchronous URL request and I don't know what object to call "reload" on.
The UITableViewController class has a property tableView to access the UITableView it's using.
So you can do that inside the RootViewController class:
[self.tableView reload];
When a button is pushed in one of my app's table view cells, I need to push a certain view controller onto the navigation stack.
This could be done by using an instance of NSNotification to inform the table view's controller of the button press. But that would be awfully heavyweight, especially since selections in a tab bar in the app could cause the table view to appear or disappear, creating additional overhead as the various table views register and unregister themselves whenever they are tabbed onto or off of the screen.
Can anyone think of a better solution?
Why not put
[[self navigationController] pushViewController:targetViewController animated:YES];
in the method called by the button?
Make your UITableViewController use the UITableViewDelegate Protocol and implement this method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
From the indexPath you can get which row has been pressed and then you know which cell is being selected. The purpose of the UITableViewController is to know about the cells and the cell itself does not need a button to trigger an event to push a new view.
What I did was set the table view's delegate to be the same as its controller. Then:
UITableView *myTableView = (UITableView *)self.superview;
NSIndexPath *indexPath = [myTableView indexPathForCell: self];
MyTableViewController *myTableViewController = (MyTableViewController *)(myTableView.delegate);
[myTableViewController buttonWasPressedOnCellWithIndexPath: indexPath];