i'm trying to perform something pretty simple which is:
I have a home page view controller and a table view controller (separate controllers) which supports deleting cells.
In the home page I have a UILabel object which I want to populate with the first cell in the table view controller. So I figured what I need is to create an instance of my table view controller in my home page view controller and ask this information...but from some reason the object i'm getting from the table view controller called "currentTarget" is nil...(and it's not).
This is my HomeViewController: (just the relevant lines)
#import "StackTableViewController.h"
#interface HomeViewController ()
#property (strong, nonatomic) IBOutlet UILabel *homeLabel;
#end
#implementation HomeViewController
- (id)init {
self = [super initWithNibName:#"HomeViewController" bundle:nil];
if (self) {
// Do something
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self.navigationController setNavigationBarHidden:YES];
self.homeLabel.font = [UIFont fontWithName:#"Candara-Bold" size:40];
StackTableViewController *svc = [[StackTableViewController alloc] init];
self.homeLabel.text = svc.currentTarget;
}
This is my StackTableViewController.m: (just the relevant lines)
#import "StackTableViewController.h"
#import "Target.h"
#import "StackTableViewCell.h"
#import "HomeViewController.h"
#import "CoreDataStack.h"
#interface StackTableViewController () <NSFetchedResultsControllerDelegate>
#property (nonatomic, strong) NSFetchedResultsController *fetchedResultController;
#end
#implementation StackTableViewController
- (id)init {
self = [super initWithNibName:#"StackTableViewController" bundle:nil];
if (self) {
// Do something
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
[self.fetchedResultController performFetch:nil];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
Target *current = [self.fetchedResultController objectAtIndexPath:indexPath];
self.currentTarget = current.body;
}
And also added this code in the prepare for segue method so the currentTarget will get updated coming back from segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
[self.fetchedResultController performFetch:nil];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
Target *current = [self.fetchedResultController objectAtIndexPath:indexPath];
self.currentTarget = current.body;
}
why my label won't show up :/?
tnx ahead
The problem is that your init method does not initialise either the fetched results controller or the currentTarget property. They are only initialised When you present that table view controller and the viewDidLoad method runs. If you move (or copy) these lines to your init method, it should work:
[self.fetchedResultController performFetch:nil];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
Target *current = [self.fetchedResultController objectAtIndexPath:indexPath];
self.currentTarget = current.body;
In your StackTableViewController.m:
- (id)init {
self = [super initWithNibName:#"HomeViewController" bundle:nil];
if (self) {
[self.fetchedResultController performFetch:nil];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
Target *current = [self.fetchedResultController objectAtIndexPath:indexPath];
self.currentTarget = current.body; }
return self;
}
Related
I used the Master - Detail application to create a new project in xcode. Each time I run my program, the rows are not visible in the master view. Thanks in advance! Please check my code below...
MasterViewController.h
#import <UIKit/UIKit.h>
#class DetailViewController;
#interface MasterViewController : UITableViewController
#property (strong, nonatomic) DetailViewController *detailViewController;
#end
MasterViewController.m
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MasterViewController ()
#property NSMutableArray *objects;
#end
#implementation MasterViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] ***emphasized text***initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
self.detailViewController = (DetailViewController *) [[self.splitViewController.viewControllers lastObject] topViewController];
}
-(void)viewWillAppear:(BOOL)animated {
self.clearsSelectionOnViewWillAppear = self.splitViewController.isCollapsed;
[super viewWillAppear:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender {
if (!self.objects) {
self.objects = [[NSMutableArray alloc] init];
}
[self.objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Segues
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = self.objects[indexPath.row];
DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
[controller setDetailItem:object];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
}
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section {
return self.objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSDate *object = self.objects[indexPath.row];
cell.textLabel.text = [object description];
return cell;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
#end
DetailViewController.h
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController
#property (strong, nonatomic) id detailItem;
#property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#end
DetailViewController.m
#import "DetailViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
#pragma mark - Managing the detail item
-(void)setDetailItem:(id)newDetailItem {
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
-(void)configureView {
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
-(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I figured, if you scale the size of the device to 75% and 100%, the rows will display. I guess this has something to do with xcode.
i have 2 view controllers:
StackTableViewController.m:
#interface StackTableViewController () <NSFetchedResultsControllerDelegate>
#property (nonatomic, strong) NSFetchedResultsController *fetchedResultController;
#end
#implementation StackTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.fetchedResultController performFetch:nil];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
Target *record = [self.fetchedResultController objectAtIndexPath:indexPath];
self.currentTarget = record.body;
}
HomeViewController.m
#import "HomeViewController.h"
#import "CreateViewController.h"
#import "StackTableViewController.h"
#interface HomeViewController ()
#property (strong, nonatomic) IBOutlet UILabel *targetLabel;
#end
#implementation HomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
StackTableViewController *vc = [[StackTableViewController alloc] init];
NSString *current = vc.currentTarget;
// Do any additional setup after loading the view.
self.targetLabel.text = current;
}
but something wrong with the HomeViewController because it's not populating the label..
how can i solve it?
tnx
You should probably update the label's text within ViewWillAppear of the StackTableViewController
Also, is currentTarget set up in StackTableViewController's init method? If not, it won't be initialized and that would be why you're not getting anything in HomeViewController's label
Explanation
viewDidLoad is not called instead, or before the init! It's called sometime after the init method finishes.
What happens:
- (void)viewDidLoad {
[super viewDidLoad];
StackTableViewController *vc = [[StackTableViewController alloc] init]; // init is called on vc object
NSString *current = vc.currentTarget; // ViewDidLoad was not yet called on vc object!
self.targetLabel.text = current;
}
/// ViewDidLoad will be called on vc object sometime after leaving this method!
What happens is:
You call StackTableViewController *vc = [[StackTableViewController alloc] init]; which sends a message init to the object.
You don't have init method in your implementation so the init of superclass (UIViewController) is called. When you instantiate your ViewController it begins loading view. Only after it's done loading ViewDidLoad will be called.
Please read any article on ViewController's lifecycle .
Solution
Fastest solution to your problem: create a delegate in your table, and inform when it's done loading using delegates, like this:
Table view controller
#implementation StackTableViewController
{
id<TargetChangedDelegate> _myDelegate;
}
-(id)initWithDelegate:(id<TargetChangedDelegate>)delegate
{
_myDelegate= delegate;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.fetchedResultController performFetch:nil];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
Target *record = [self.fetchedResultController objectAtIndexPath:indexPath];
self.currentTarget = record.body;
// inform your delegate
[_myDelegate targetChanged];
}
Home view controller
#interface HomeViewController () <TargetChangedDelegate>
#property (strong, nonatomic) IBOutlet UILabel *targetLabel;
#end
#implementation HomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
StackTableViewController *vc = [[StackTableViewController alloc] initWithDelegate:self];
}
- (void)targetChanged
{
NSString *current = vc.currentTarget;
// Do any additional setup after loading the view.
self.targetLabel.text = current;
}
I am new to Ios programming i want to display the data from master view controller into the detail view controller, i am using the master detail template from xcode. the detail array is working it shows the detail in label, how ever i want to display the title as well which is stored in _objects array,
here is my code
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MasterViewController () {
NSMutableArray *_detailObjects;
NSMutableArray *_thumbnailImage;
}
#end
#implementation MasterViewController
#synthesize _objects;
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title= #"Zodiac List";
_objects = [[NSMutableArray alloc] initWithObjects:
#"value 1",
#"value 2",
#"value 3",
#"value 4",
#"value 5",
,nil];
_detailObjects = [[NSMutableArray alloc] initWithObjects:
#"detail of value 1",
#"detail of value 2",
#"detail of value 3",
#"detail of value 4",
#"detail of value 5",
, nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSDate *object = _objects[indexPath.row];
cell.textLabel.text = [object description];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSMutableArray *object = _detailObjects[indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}
#end
the detail is working fine how ever i want to display the value 1, value 2,value 2 in a label as well..
here is my detail view controller code..
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) id detailItemTitle;
#property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#property (weak, nonatomic) IBOutlet UILabel *zodiacNameLabel;
here is .m file code
#import "DetailViewController.h"
#import "MasterViewController.h"
#interface DetailViewController ()
- (void)configureView;
#end
#implementation DetailViewController
#synthesize zodiacNameLabel;
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
-(void) setDetailItemTitle:(id)detailItemTitle{
if (_detailItemTitle !=detailItemTitle) {
_detailItemTitle = detailItemTitle;
[self configureView];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
// self.zodiacNameLabel.text = [self.]
MasterViewController *master = [[MasterViewController alloc] init];
zodiacNameLabel.text = [master._objects objectAtIndex:0];
}
// if (self.detailItemTitle) {
// self.zodiacNameLabel.text = [self.detailItem description];
// }
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
// MasterViewController *master = [[MasterViewController alloc] init];
// zodiacNameLabel.text = [master._objects objectAtIndex:0];
// MasterViewController *master = [[MasterViewController alloc]init];
// zodiacNameLabel.text = [master._objects objectAtIndex:0]; // you can get first element of an array
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Implement delegate method of tableview which is in your masterviewcontroller and then inside that push your data whatever you want to display in masterviewcontroller like that:-
Assuming that below delegate is in your masterViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_yourController = [[yourController alloc] initWithNibName:#"yourController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:_yourController animated:YES];
}
Now this will alloc, initialize and load your nib into detailviewcontroller and if you want to send message from master to detail then declare property method in detailviewcontroller and just pass it from above like that below:-
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_yourDetailController = [[yourDetailController alloc] initWithNibName:#"yourDetailController" bundle:[NSBundle mainBundle]];
[_yourDetailController setTempString:#"test"]; //Assuming that tempString is declared in yourDetailController class
[self.navigationController pushViewController:_yourDetailController animated:YES];
}
Make an array that is "tmpArray" in detailViewController and then you can copied _objects array in to tmpArray. like this
MastrerViewController.m
DetailViewController *detail = [[DetailViewController alloc]init];
detail.tmpArray = [[NSMutableArray alloc] initWithArray:_objects];
DetailViewController.h
#property (nonatomic,retain) NSMutableArray *tmpArray;
I have a tableview controller that is a static table used for request data. When someone selects a row, it displays a new tableview controller with options using a modal segue, the user selects a option and then presses the 'hecho' (done) button and the value should be returned to the first table view controller, but it just not happening. If I inspect the delegate it just says null. What could I be doing wrong?
The story board
First table
AgregarCitaTableViewController.h
#import <UIKit/UIKit.h>
#import "SeleccionarPacienteTableViewController.h"
#interface AgregarCitaTableViewController : UITableViewController <SeleccionarPacienteTableViewControllerDelegate>
#end
AgregarCitaTableViewController.m
#import "AgregarCitaTableViewController.h"
#import "SeleccionarPacienteTableViewController.h"
#interface AgregarCitaTableViewController ()
{
NSDictionary *datosPaciente;
}
#end
#implementation AgregarCitaTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)paciente:(NSDictionary *)paciente
{
datosPaciente = paciente;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
cell.detailTextLabel.text = [datosPaciente objectForKey:#"nombre"];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"listaPacientes"] )
{
SeleccionarPacienteTableViewController *viewController = segue.destinationViewController;
viewController.delegate = self;
}
}
Second Table
SeleccionarPacienteTableViewController.h
#protocol SeleccionarPacienteTableViewControllerDelegate <NSObject>
-(void)paciente:(NSDictionary *)paciente;
#end
#interface SeleccionarPacienteTableViewController : UITableViewController
{
id delegate;
}
#property(nonatomic,assign)id<SeleccionarPacienteTableViewControllerDelegate> delegate;
#end
SeleccionarPacienteTableViewController.m
#import "SeleccionarPacienteTableViewController.h"
#interface SeleccionarPacienteTableViewController ()
{
NSMutableArray *todosPacientes;
NSDictionary *paciente;
NSInteger checkmarkedRow;
}
#end
#implementation SeleccionarPacienteTableViewController
#synthesize delegate = _delegate;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
UIBarButtonItem *hecho = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(hecho)];
[[self navigationItem] setRightBarButtonItem:hecho];
UIBarButtonItem *cancelar = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelar)];
[[self navigationItem] setLeftBarButtonItem:cancelar];
//Llamada asincrona, cargar las citas
[self performSelectorInBackground:#selector(cargarDatos) withObject:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return todosPacientes.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSDictionary *object;
object = todosPacientes[indexPath.row];
cell.textLabel.text = [object objectForKey:#"nombre"];
if(checkmarkedRow == indexPath.row){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Guardar nombre del paciente selccionado
paciente = todosPacientes[indexPath.row];
// In cellForRow... we check this variable to decide where we put the checkmark
checkmarkedRow = indexPath.row;
// We reload the table view and the selected row will be checkmarked
[tableView reloadData];
// We select the row without animation to simulate that nothing happened here :)
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
// We deselect the row with animation
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void) cargarDatos
{
//Path donde se encuentra el plist con los datos
NSString *path = [[NSBundle mainBundle]pathForResource:#"pacientes" ofType:#"plist"];
//Guardamos las citas en un NSMutableArray
todosPacientes = [[NSMutableArray alloc]initWithContentsOfFile:path];
}
- (void) hecho
{
/*Is anyone listening
if([delegate respondsToSelector:#selector(paciente:)])
{
//send the delegate function with the amount entered by the user
[delegate paciente:paciente];
}*/
[self.delegate paciente:paciente];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void) cancelar
{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Solution:
Im not really sure how it worked or even if this is the real solution. I used the anwer of Hani Ibrahim and it didn't work but what he said was right. Then i just changed [delegate paciente:paciente] in the hecho method for [self.delegate paciente:paciente] and it worked.
I hope this can help someone.
The problem is that your seque display UINavigationController and not SeleccionarPacienteTableViewController
Change this method
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"listaPacientes"] )
{
SeleccionarPacienteTableViewController *viewController = segue.destinationViewController;
viewController.delegate = self;
}
}
to be
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"listaPacientes"] )
{
UINavigationController *navController = segue.destinationViewController;
SeleccionarPacienteTableViewController *viewController = [navController.viewControllers objectAtIndex:0];
viewController.delegate = self;
}
}
You have another problem
When doing this
#property(nonatomic,assign)id<SeleccionarPacienteTableViewControllerDelegate> delegate;
and this
#synthesize delegate = _delegate;
Then Your property will work with an instance variable called '_delegate' as you are saying #synthesize delegate = _delegate;
However this code
#interface SeleccionarPacienteTableViewController : UITableViewController
{
id delegate;
}
defines a new instance variable called delegate which is completely different than your property
So to access your property you can use self.delegate or _delegate and NOT delegate as it is another instance variable !
I think the problem is in prepareForSegue. The destinationViewController is a UINavigationController and not a SeleccionarPacienteTableViewController.
You have to access the first child of the destinationViewController to get your SeleccionarPacienteTableViewController.
Replacing segue.destinationViewController with [segue.destinationViewController topViewController] will probably solve your problem.
My app have core data and two views CoursesTableViewController and DetailViewController.
If the user tap on Detail Disclosure button segue to DetailViewController to show some details.
The app uses didSelectRowAtIndexPath and didDeselectRowAtIndexPath for other things.
CoursesTableViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
[[segue destinationViewController] setDetailItem:object];
}
}
DetailViewController.h
#property (strong, nonatomic) id detailItem;
#property (weak, nonatomic) IBOutlet UITextField *courseCodeLabel;
#property (weak, nonatomic) IBOutlet UITextField *courseNameLabel;
DetailViewController.m
#interface DetailViewController ()
- (void)configureView;
#end
#implementation DetailViewController
#synthesize detailItem = _detailItem;
#synthesize courseCodeLabel = _courseCodeLabel;
#synthesize courseNameLabel = _courseNameLabel;
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.courseCodeLabel.text = [[self.detailItem valueForKey:#"courseCode"] description];
self.courseNameLabel.text = [[self.detailItem valueForKey:#"courseName"] description];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
self.courseCodeLabel = nil;
self.courseNameLabel = nil;
}
The problem is when I tap on Detail Disclosure the segue works good but in the DetailViewController there are no value in the courseCodeLabel and courseNameLabel.
Import & try casting the destination view controller.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
DetailViewController * detailVC = (DetailViewController *)[segue destinationViewController];
[detailVC setDetailItem:object];
}
}