From my TableView I dynamically want to show either a TableView or a DetailView (new segue), based on the cell's content. I setup two segues from the TableView to different DetailViews and one segue from the TableViewCell to the TableView.
I have almost completed the implementation using performSegueWithIdentifier: (see below), but there is one struggling issue remaining: after I call [self dismissModalViewControllerAnimated:YES]; on the DetailView it returns to an empty TableView . I assume because the Storyboard segue from the UITableViewCell is performed. By clicking the back button I return to my original (parent) TableView data.
Any suggestions for this work?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"%s", __PRETTY_FUNCTION__);
NSString *type = [[self.dataController objectInListAtIndex:[self.tableView indexPathForSelectedRow].row] valueForKey:#"cell_type"];
NSLog(#"cell_type: %#", type);
if([[segue identifier] isEqualToString:#"DetailSegue"])
{
UIViewController *detailViewController = [segue destinationViewController];
detailViewController.game = [self.dataController objectInListAtIndex:[self.tableView indexPathForSelectedRow].row];
} else if ...
} else if([[segue identifier] isEqualToString:#"TableViewSegue"]){
if([type isEqualToString:#"TableView"]){
//Create child ViewController, a custom ViewController with custom initWithId:Title:
CategoryViewController *categoryViewController = [[segue destinationViewController] initWithId:categoryId Title:categoryTitle];
}
}
}
I would create in my tableview multiple cells. Each with its own identifier. Then connect each cell to its own detailviewcontroller. You can also connect a cell to its own view controller (creating drill down functionality for only specific cell).
Thats all...
Related
I am writing an iOS app that uses the service Parse. When I tap on a cell, it doesn't segue as I would expect. It appears that my "prepareForSegue" method is not being called. I used breakpoints to determine this, and the NSLog never outputs anything. Here is my method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
NSLog(segue.identifier);
if ([segue.identifier isEqualToString:#"showObjectDetails"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
//OfferDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
[segue.destinationViewController setObject:object];
}
}
The segue name is "showObjectDetails" if it matters, and it's coming from a list view. I used the Push selection segue. I have made sure that the Custom Class is set correctly in Interface Builder. I am using a Tab Bar controller, that references a NavigationController, that then displays the tableview.
Make sure that the Segue Identifier has been set in the Storyboard, as below.
I have a project with a TabBar Controller with a Navigation Controller and other View Controllers on it.
In my Navigation controller i have a sequence of 3 view controller and the last of them, DetailViewController, is being presented using a modal transition. I'm parsing strings between my 2nd and 3rd view controllers, but my labels displaying the information on the 3rd one only display after selecting a cell twice, and the information that shows is the one corresponding to the first selection of the cell.
Heres my 2nd view controller (ViewController) method prepareForSegue:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
titulo=[nomeEvent objectAtIndex:indexPath.row];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"nextView"]) {
DetailEventViewController *myVC = [segue destinationViewController];
myVC.tituloEvento = titulo;
}
}
The property tituloEvento is declared in the second view controller's .h and in viewwillappear I set my labels text.
This might be happening because prepareForSegue is getting called before didSelectRowAtIndexPath:. Here is what I would do:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"nextView"]) {
DetailEventViewController *myVC = [segue destinationViewController];
NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
myVC.tituloEvento = [nomeEvent objectAtIndex:selectedIndexPath.row];
}
}
I have a simple storyboard file with a table view inside a navigation controller. If you cick one of the cells it goes to the details view. Great.
Then I tried adding a toolbar button and hooking it up to my table view controller. The button and the seque seems to work fine, except now, when i click on one of the table cells, the modal view is triggered.
So it seems I have done something wrong, but I don't understand what.
// called by pressing the add button in the toolbar
- (IBAction)showAddEventView:(id)sender {
[self performSegueWithIdentifier:#"showAddEvent" sender:sender];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showAddEvent"]) {
AddEventVC *addEventVC = [[AddEventVC alloc] init];
// set some property
} else {
EventIndexVC *eventIndexVC = [segue destinationViewController];
eventIndexVC.eventTitle = [self.events objectAtIndex: [[self.tableView indexPathForSelectedRow] row]];
}
}
I want to simply set the title on my destination view controller so that it shows in its navigation controller's navigation bar in the prepareForSegue: method however setting its title or navigationItem like so:
[segue.destinationViewController setTitle:#"doesn't work"];
[segue.destinationViewController.navigationItem setTitle:#"this either"];
doesn't work possibly because the destination's view controller's view isn't loaded yet. Can I do this without creating a custom destination view controller?
Try accessing your ViewController that is embedded in the UINavigationController like this.
First you give your segue an identifier in the interface builder, then you access the segue in the prepareForSegue method and set the title by accessing the topViewController property of the navigation controller you segue to.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"yourSegueIdentifier"]) {
UINavigationController *navController =
(UINavigationController*)[segue destinationViewController];
YourViewController *destViewController =
(YourViewController* )[navController topViewController];
destViewController.navgationItem.title.text = #"Your new title";
}
}
This is for a segue into another UITableView
Set a public NSString property in the destination UITableViewController file.
#property (strong, nonatomic) NSString *navBarTitle;
Override the setter in the .m file just to be sure.
- (void) setNavBarTitle:(NSString *)navBarTitle
{
_navBarTitle = navBarTitle;
}
In the originating tableView's segue method, pass whatever string you need in the title.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString: #"userDetails"]) {
UsersActivitiesTableViewController *destinationController = segue.destinationViewController;
//Get the index path of the cell the user just clicked
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
//Grab the object from the array of users if the next view requires a specific title for a user name etc.
UserMO *thisUser = [self.users objectAtIndex:indexPath.row];
//Pass the string you want as the title to the public NSString property
destinationController.navBarTitle = thisUser.name;
}
}
And now for the important bit....
In the destination controller, get the top controller of the view and set the title property, after the view is loaded, and before it has been displayed:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController topViewController].title = self.navBarTitle;
}
If you want a static title this can now (i.e., in Xcode 4.6.3) this can be done in Storyboard simply by setting the title in the nav bar on the relevant view controller.
If however you want the nav bar title to change according to what view is being segued to, e.g., a detail of a particular table row, as far as I know that needs to be set programmatically.
It took me FOREVER (newbie, sigh!) to figure out how to modify Julian Vogels' correct answer to call the key I wanted to use. Here's what worked:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"DetailSegue"]) {
// Fetch Item
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDictionary *item = [self.groceries objectAtIndex:[indexPath row]];
// Configure Detail View Controller
TPDetailViewController *vc = [segue destinationViewController];
vc.navigationItem.title = [item objectForKey:#"name"];
[vc setItem:item];
}
If the segue is a push segue - which it should be if you're using a UINavigationController - then the destination view controller is automatically added to the window hierarchy, and you don't even need to identify the UINavigationController:
if ([segue.identifier isEqualToString:#"yourSegueNameHere"]) {
[segue.destinationViewController setTitle:#"yourTitleHere"];
}
I have a Master-Detail application.When the user selects a row in the MasterTable, I want to open another Table (not the DetailViewController). It should paper besides the MasterViewController, similar to the Facebook app on iPad.
I have a Custom segue from the MasterViewController to this table (DocumentViewController of type UITableViewController). This DocumentViewController is 'Embedded' in a navigation controller.
In short, the items on my storyboard look like this:
navigationController->MasterViewController->navigationController->DocumentViewController.
The segue is from MasterViewController to navigationController.
Do I have to perform the segue in "didSelectRowAtIndexPath"? Or do I have to use "performSegueWithIdentifier" in didSelectRowAtIndexPath?
If I understand your question correctly, the segue should be from MasterViewController to DocumentViewController. Make sure to give it a unique identifier, and then reference what you want to do in the prepareForSegue in your MasterViewController.
Example:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showList"]) {
// gets indexPath for the currently selected row in my UITableView
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
// pull back some useful data from Core Data according to what was selected in my UITableView.
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
// listDataItem is a property of the controller (in this case a UITableViewController)
[[segue destinationViewController] setListDataItem:object];
}
}