2

I'm following closely to this hubpage http://klanguedoc.hubpages.com/hub/iOS-How-To-Display-Detail-Data-from-UITableView-in-Detail-View-Controller and am able to replicate it almost perfectly except the final component. prepareForSegue method.

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        klViewController *detailViewController = [segue destinationViewController];

        detailViewController.treeData = [self.ds objectAtIndex:[self.tableView indexPathForSelectedRow].row];

    }
}

I tried to look closely and tried finding other online example of prepareForSegue method but they were all pointing to the same direction, which means the method and code is correct!

The error issued by xcode is ARC Issue - No visible @interface for 'NSString' declares the selector 'isEqualToString:'

Can anyone please point me to the right direction?

P.S correct me if I'm wrong, but should this prepareForSegue method suppose to be in the tableview class? if it's not please let me know, cause I'm new to xcode and the tutorial is abit hazy, hence I'm afraid I miss interpret where the codes are suppose to go.

Many thanks in advance :)

EDIT:

SampleData.h

#import <Foundation/Foundation.h>

@interface SampleData : NSObject

@property (nonatomic,strong) NSString * treeName;
@property (nonatomic,strong) NSString * treeDescription;

@end

SampleData.m

#import "SampleData.h"

@implementation SampleData
@synthesize treeName, treeDescription;


@end

SampleDataDOA.h

#import <Foundation/Foundation.h>
#import "SampleData.h"
@interface SampleDataDAO : NSObject

@property (nonatomic,strong) NSMutableArray *someDataArray;

-(NSMutableArray *)PopulateDataSource;

@end

SampleDataDOA.m

#import "SampleDataDAO.h"

@implementation SampleDataDAO

@synthesize someDataArray;



-(NSMutableArray *)PopulateDataSource
{
    someDataArray= [[NSMutableArray alloc]initWithCapacity:3];
    SampleData * mydata= [[SampleData alloc]init];

    mydata.treeName = @"Oak";
    mydata.treeDescription = @"an oak is a tree or shurb bla bla bla";
    [someDataArray addObject:mydata];
    mydata=nil;

    mydata=[[SampleData alloc]init];
    mydata.treeName=@"Douglas Fir";
    mydata.treeDescription=@"Douglas Fir are medium-size to extremely large evergreen trees";
    [someDataArray addObject:mydata];
    mydata=nil;

    mydata=[[SampleData alloc]init];
    mydata.treeName=@"Sugar Maple";
    mydata.treeDescription=@"Sugar Maple is a species of Maple. Sugar Maple is best known for it's sweet leaves as it contain natural sugar and is extremely healthy and beneficial to our health";
    [someDataArray addObject:mydata];
    mydata=nil;



    return someDataArray;
}


@end

TableViewController.h

#import <UIKit/UIKit.h>
#import "SampleDataDAO.h"
#import "SampleData.h"
#import "ViewController.h"

@interface TableViewController : UITableViewController

@property(nonatomic,strong) SampleDataDAO* daoDS;
@property (nonatomic,strong) NSMutableArray *ds;


@end

TableViewController.m (error with method prepareForSegue)

#import "TableViewController.h"

@interface TableViewController ()

@end

@implementation TableViewController
@synthesize daoDS,ds;

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if( [[segue identifier] isEqualtoString:@"showDetail"]){        
        ViewController * detailViewController = [segue destinationViewController];

        detailViewController.treeData=[self.ds objectAtIndex:[self.tableView indexPathForSelectedRow].row];
    }
}


- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    daoDS = [[SampleDataDAO alloc]init];
    self.ds = daoDS.PopulateDataSource;

    // 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)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    // Return the number of rows in the section.
    return 3;
}   

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"treeCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    // Configure the cell...
    SampleData * sample = [self.ds objectAtIndex:indexPath.row];
    cell.textLabel.text = sample.treeName;
    NSLog(@"Cell Value %d %@", indexPath.row, cell.textLabel.text);




    return cell;
}





/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject: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
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     */
}

@end

ViewController.h

#import <UIKit/UIKit.h>
#import "SampleData.h"
@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UITextView *treeInfo;
@property (nonatomic, strong) SampleData * treeData;

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize treeData, treeInfo;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}   

@end

P.S - the code are almost similar to the 1 in the website with the main difference being me having removed the picture portion of the code.

EDIT - error log file no visible @interface for 'NSString' declares the selector 'isEqualtoString:' if( [[segue identifier] isEqualtoString:@"showDetail"]){

the error underline is at the "[[" Hope this is a helpful hint to you guys finding out the real error ._.

Yang Jie Domodomo
  • 685
  • 1
  • 8
  • 25
  • this post may be helpful: http://stackoverflow.com/questions/7864371/ios5-how-to-pass-prepareforsegue-an-object – Mike May 31 '12 at 12:48

2 Answers2

1

So when your dealing with iOS you are in the MVC architecture which means that you have ViewControllers which control your storyboards so your prepareForSegue method should be in the ViewController class that corresponds to the view that is transitioning.

Maybe look at your storyboard in the identity inspector on the right. Make sure that the "Custom Class" is the view controller you are using that has the prepareForSegue method in it

Without seeing a bit more code, it is tough to tell, but this link seems like it might have what you need: "No visible @interface for 'BlahDataController' declares the selector 'aMethod:'"

If this link doesn't work, try looking through each step of the given tutorial again. You might find something.

Cheers

Community
  • 1
  • 1
onetwopunch
  • 3,279
  • 2
  • 29
  • 44
  • I've edited and added in the code. I tried to look through the step of the tutorial for a few days, even redoing the whole tutorial twice, but ended up with the same problem. – Yang Jie Domodomo May 31 '12 at 07:05
1

For one thing, change:

if ([[segue identifier] isEqualToString:@"showDetail"]) {

to

if ([segue.identifier isEqualToString:@"showDetail"]) {

and

klViewController *detailViewController = [segue destinationViewController];

to

klViewController *detailViewController = segue.destinationViewController;

Also, what I tend to do is to wire the segue up to the ViewController or TableViewController itself and NOT to the tableview cell. Then in the cellForRowAtIndexPath, I would do fire off the segue and pass in the IndexPath like this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self performSegueWithIdentifier:@"showDetail" sender:indexPath];
}

Then using your prepareForSegue method I would do this instead:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if ([segue.identifier isEqualToString:@"showDetail"]) {
        // Get the indexPath
        NSIndexPath *indexPath = (NSIndexPath *)sender;

        klViewController *detailViewController = segue.destinationViewController;
        detailViewController.treeData = [self.ds objectAtIndex:indexPath.row;
    }
}
LJ Wilson
  • 14,445
  • 5
  • 38
  • 62
  • ok thanks! I'll try it the first thing in the morning tomorrow when I arrive at my work station. – Yang Jie Domodomo May 31 '12 at 12:40
  • If i change to detailViewController.treedata = [self.ds objectAtIndex:(NSIndexPath *)sender]; i will get a caution saying : incompatible pointer to integer conversion sending 'NSIndexPath' to parameter of type 'NSUInteger'(aka 'unsigned int'). and the red error is still prevailing. – Yang Jie Domodomo Jun 01 '12 at 03:39
  • The OP didn't say, but it is safe to assume that it stands for "Data Source" and is an NSArray or NSMutableArray. – LJ Wilson Mar 26 '13 at 22:28