Cannot pass value from UITableViewCell to a detail view - objective-c

I am trying to change the color of a label in my detail view based on which cell is touched in a table view.
I just can't make this happen. Below is my code. I have included the header file from the detail view, and created an IBOutlet for the label.
Update: Ideally, when I clicked on a cell, the label color in detailview should be red. And here is a screencast about my problem. http://www.youtube.com/watch?v=i0nhbsNJWHY&feature=youtube_gdata_player
#pragma mark - TableView Delegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"ReferenceDetail" sender:tableView];
}
#pragma mark - Segue
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ReferenceDetail"]) {
ReferenceDetailViewController *referenceDetailViewController = [segue destinationViewController];
UIViewController *referenceDetailView = [segue destinationViewController];
if(sender == self.searchDisplayController.searchResultsTableView) {
NSIndexPath *indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
NSString *destinationTitle = [[filteredReferenceArray objectAtIndex:[indexPath row]] name];
[referenceDetailView setTitle:destinationTitle];
}
else {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *destinationTitle = [[referenceArray objectAtIndex:[indexPath row]] name];
[referenceDetailView setTitle:destinationTitle];
[referenceDetailViewController.label1 setTextColor:[UIColor redColor]];
}
}
}

The problem you are having is that the outlet UILabel inside your ReferenceDetailViewController has not loaded up from the xib, yet you are trying to set it's textColor property.
As a way to make sure this is the problem, try setting a breakpoint in the line where you set the color and another breakpoint inside the ReferenceDetailViewController [viewDidLoad] method. The line where you setup the color should be getting called first.
A simple solution to your problem is to have a property on your ReferenceDetailViewController class that "holds" the UIColor instance and later set it on the viewDidLoad method:
// ...
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ReferenceDetail"]) {
ReferenceDetailViewController *referenceDetailViewController = [segue destinationViewController];
UIViewController *referenceDetailView = [segue destinationViewController];
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *destinationTitle = [[referenceArray objectAtIndex:[indexPath row]] name];
[referenceDetailView setTitle:destinationTitle];
referenceDetailViewController.auxTextColor = [UIColor redColor];
}
// ..
And in ReferenceDetailViewController:
#interface ReferenceDetailViewController : UIViewController
#property (retain, nonatomic) UIColor *auxTextColor;
// ...
#end
#implementation ReferenceDetailViewController
- (void)viewDidLoad
{
[super viewDidLoad];
label1.textColor = self.auxTextColor;
// ...
}
#end
If you must do this for a set of labels, it'd be wise to have a NSDictionary object to hold these properties for you.

The outlets are not setup yet when you segue so you can't get to them to change them. Try sending some object or something over and in the viewdidload of the viewcontroller you segue to you read that and then use that as the way to know what color to change to and then in that same code you change the color of the label.

Related

CollectionViewController not seeing properties on the DetailViewController

I'm a novice and I'm trying to understand why my CollectionViewController is not seeing properties on the DetailViewController...any tips or insight would be appreciated. Code below...for my detailViewController.h and also my CollectionViewController.m, respectively.
// DetailViewController.h
// RecipePhoto
//
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIImageView *recipeImageView;
#property (nonatomic) NSString *recipeImageName;
- (IBAction)close:(id)sender;
#end
#import "RecipeCollectionViewController.h"
#import "DetailViewController.h".
#interface RecipeCollectionViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
{
NSArray *recipeImages;
}
#end
#implementation RecipeCollectionViewController
static NSString * const reuseIdentifier = #"Cell";
- (void)viewDidLoad {
[super viewDidLoad];
recipeImages = [NSArray arrayWithObjects:#"angry_birds_cake.jpg", #"creme_brelee.jpg", #"egg_benedict.jpg", #"full_breakfast.jpg", #"green_tea.jpg", #"ham_and_cheese_panini.jpg", #"ham_and_egg_sandwich.jpg", #"hamburger.jpg", #"instant_noodle_with_egg.jpg", #"japanese_noodle_with_pork.jpg", #"mushroom_risotto.jpg", #"noodle_with_bbq_pork.jpg", #"starbucks_coffee.jpg", #"thai_shrimp_cake.jpg", #"vegetable_curry.jpg", #"white_chocolate_donut.jpg", nil];
}
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipePhoto"]) {
NSArray *indexPaths = [self.collectionView indexPathsForSelectedItems];
// Get the new view controller using [segue destinationViewController].
DetailViewController *detailViewController = [segue destinationViewController];
NSIndexPath *indexPath = [indexPaths objectAtIndex:0];
// Pass the selected object to the new view controller.
DetailViewController.recipeImageName = [recipeImages[indexPath.section] objectAtIndex:indexPath.row];
[self.collectionView deselectItemAtIndexPath:indexPath animated:NO];
}
}
#pragma mark <UICollectionViewDataSource>
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
//return arrayName.count;
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return recipeImages.count;
}
//provides the data for the collection view cells
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
// Configure the cell
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:[recipeImages objectAtIndex:indexPath.row]];
return cell;
}
You are trying to use recipeImageName as a class property in prepareForSegue:
DetailViewController.recipeImageName = [recipeImages[indexPath.section] objectAtIndex:indexPath.row];
should be
detailViewController.recipeImageName = [recipeImages[indexPath.section] objectAtIndex:indexPath.row];
Pay close attention to the capitalisation of the first letter. DetailViewController is the class; detailViewController is the local variable.

The indexPath of custom table cell is undefined, objective c

I have created a custom cell call PendingDoctorTableViewCell and is used in PendingDoctorTableView. Everything is work find and i added a disclosure indicator by using
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
It's able to performed the segue "ShowPendingDoctor".
However when i used the prepareForSegue, the indexPath is undefined.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"ShowPendingDoctor"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
ActionForPendingDoctorViewController *destViewController = segue.destinationViewController;
destViewController.myObjects = [myObject objectAtIndex:indexPath.row];
// Hide bottom tab bar in the detail view
// destViewController.hidesBottomBarWhenPushed = YES;
}
}
How can i get to know which row had been tap. because its always return the object of 1st index.
Anyone can help me? i'm rushing for my project. Thanks.
Declare a variable of NSIndexPath to save your currently selected indexPath
NSIndexPath *selectedIndexPath;
Use Tableview delegate to identify selected row and perform segue programmatically
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:YOUR_SEGUE_IDENTIFIER sender:self];
}
Pass your object to next ViewController through prepareForSegue
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:YOUR_SEGUE_IDENTIFIER])
{
ActionForPendingDoctorViewController *destViewController = segue.destinationViewController;
destViewController.myObjects = [myObject objectAtIndex:selectedIndexPath.row];
}
}

Change data of a button according to selected Row in TableView

I'm trying to change the destination of a button using the selected Row of a tableViewCell.
How would I do that? I know how to change the text in a UILabel. Would it be something like that? I'm using this in my MainView to get to the DetailView:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"toDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *destViewController = segue.destinationViewController;
destViewController.nameIdentity = [nameData objectAtIndex:indexPath.row];
}
}
And in my DetailView.m:
{
[super viewDidLoad];
nameLabel.text = nameIdentity;
}
I used a NSArray for my data. Is that the correct way to go for the numbers as well?
I`m using X-Code 4.6, Objective-C, Storyboard.
Could this work? (I can't test it on an actual Device yet)
MainView.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"toDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *destViewController = segue.destinationViewController;
destViewController.numberIdentity = [numberData objectAtIndex:indexPath.row];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
numberData = [NSArray arrayWithObjects:/*1*/#"5552525",/*2*/#"5553456", nil];
}
DetailView.m
-(IBAction)callCell {
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString:numberIdentity]];
}
How can I fire a message to the debugger?

Storyboard Preparing for Seque+Passing over data

I have a detail view controller that is hooked up to a table view cell. I have a data model. It is an NSObject and has a NSMutableArray will all my properties I need in them.
I hooked up a label to an #property and named it questionLabel. For some reason, when I push over to the detail view, it does not display the question I put in the data model for the NSMutableArray.
At first I thought the segue was not working, but when I tried to change the navigation bar title, it worked when I passed my data from my NSMutableArray.
Anyone know what I am doing wrong with my label?
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"pushDetail"])
{
// Create an instance of our DetailViewController
DetailQuestionViewController *DQV = [[DetailQuestionViewController alloc] init];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
// Setting DQV to the destinationViewController of the seque
DQV = [segue destinationViewController];
Question *selectedQuestion = [self.myQuestionList questionAtIndex:path.row];
DQV.questionLabel.text = [selectedQuestion questionName];
DQV.navigationItem.title = [selectedQuestion questionRowName];
}
}
UPDATE (For: adambinsz)
Table view
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"pushDetail"])
{
// Create an instance of our DetailViewController
DetailQuestionViewController *DQV = [[DetailQuestionViewController alloc] init];
// Setting DQV to the destinationViewController of the seque
DQV = [segue destinationViewController];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
Question *selectedQuestion = [self.myQuestionList questionAtIndex:path.row];
DQV.detailItem = selectedQuestion;
}
}
detailView
- (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) {
Question *theQuestion = (Question *)self.detailItem;
self.questionLabel.text = theQuestion.questionName;
NSLog(#"The Question's questionName is %#", theQuestion.questionName);
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
}
The reason I think it may not be working, is because the if statement for self.detailItem is not checking it correctly.
The method gets called just not the detailItem.
Your label probably hasn't been created yet when you try to set its text. I would create a selectedQuestion instance variable on DetailQuestionViewController and set it when you create the view controller. Something like this:
// Create an instance of our DetailViewController
DetailQuestionViewController *DQV = [[DetailQuestionViewController alloc] init];
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
// Setting DQV to the destinationViewController of the seque
DQV = [segue destinationViewController];
DQV.selectedQuestion = [self.myQuestionList questionAtIndex:path.row];
And in DetailQuestionViewController's viewDidLoad method, set your label's text by using:
self.questionLabel.text = [selectedQuestion questionName];
self.navigationItem.title = [selectedQuestion questionRowName];

How to seque a subclass of UITableViewCell?

I've created a subclass of UITableViewCell. Until now, I've only been using cells which is "designed" in my storyboard where I can setup segues.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
[super prepareForSegue:segue sender:sender];
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
if ([[segue identifier] isEqualToString:#"showNews"]) {
NewsViewController *newsViewController = [segue destinationViewController];
News *news = (News*)[self.fetchedResultsController objectAtIndexPath:indexPath];
newsViewController.news = news;
}
}
After I've created my subclass of UITableViewCell I'm no longer able to use the Storyboard to create segues for the custom cell, right? I've tried to create a cell in the storyboard and set its class to my custom class -- but then the cell is just blank when I run the App.
So instead I'm just alloc and init the custom cell in my tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"WSTableViewCell";
WSTableViewCell *cell = (WSTableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[WSTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
WSObject *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
[cell.titleLabel setText:item.title];
return cell;
}
Then in tableView:didSelectRowAtIndexPath I'm trying to creating the NewsViewController, setting the news item and push it to the navigationController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
News* news = [self.fetchedResultsController objectAtIndexPath:indexPath];
NewsViewController *newsViewController = [[NewsViewController alloc] init];
newsViewController.news = news;
[[self navigationController] pushViewController:newsViewController animated:YES];
}
But when I select a row my NewsViewController is not shown -- but instead I see a blank view with a black background. How can I deal with this? Is it possible to still use seques?
The problem I think is that you are using alloc-init to instantiate NewsViewController. That does not create your NewsViewController from storyboard. You have to use [UIStoryboard instantiateViewControllerWithIdentifier:(NSString *)identifier] to instantiate from storyboard.
However, I think the easier way is to call
[self performSegueWithIdentifier:#"showNews" sender:indexPath]
in your didSelectRowAtIndexPath. You have to change your prepareForSegue... a little bit.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSIndexPath *indexPath = (NSIndexPath *)sender;
if ([[segue identifier] isEqualToString:#"showNews"]) {
NewsViewController *newsViewController = [segue destinationViewController];
News *news = (News*)[self.fetchedResultsController objectAtIndexPath:indexPath];
newsViewController.news = news;
}
}