2

I have a TabBarController with 4 tabs, 3 of which are table views. I am trying to put a detail for every table view cell, and I don't think storyboard is efficient since I have over 50 detail pages. I'm very new to all of this, and I've tried to find out how to link a detail to every tab for a couple hours. My table views start with the Second View Controller. Here is SecondViewController.m:

#import "SecondViewController.h"
@implementation SecondViewController
{
    NSArray *tableData;
}
@synthesize tableData;

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    tableData = [NSArray arrayWithObjects:@"Carter", @"Greene", @"Hancock", @"Hawkins", @"Johnson", @"Sullivan", @"Unicoi", @"Washington", nil];
    [super viewDidLoad];

}

#pragma mark - TableView Data Source methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:    (NSInteger)section
{
    return [tableData count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:    (NSIndexPath *)indexPath
{

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyCell"];
    }

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.textLabel.text = [tableData objectAtIndex:indexPath.row];


    return cell;
}

@end

Here is SecondViewController.h:

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController <UITableViewDelegate,
UITableViewDataSource>

@property(nonatomic, retain) NSArray *tableData;
@end

If this helps, here is my storyboard.

imgur.com/f9xdo0E

If anyone can help me individually add details to each table view cell in the most painless way possible, I would appreciate it. Thanks!

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • You would probably need to explain more as to what you mean by detail? Open a detail view controller when user taps on one of your cell? Please elaborate. – Gurtej Singh Aug 09 '15 at 02:59
  • I use Swift so unfortunately I may not be able to elaborate for you in Obj-C, but I can provide a high level solution. You should create another `UIViewController`.....say `DetailViewController`. You can set it up how you want visually, then when a user clicks on a `TableViewCell`, perform a segue to the `DetailViewController` and pass the data from the cell to the view controller. – Kyle H Aug 09 '15 at 03:01
  • 1
    Why do you think storyboard would be not efficient? In my experience, you can have a pretty silly number of objects in a storyboard, and they're split up and loaded in parts at runtime, there's rarely any runtime issue. Also, do you really have 50 *different* detail pages, or would they all be the same layout just with different content? – zpasternack Aug 09 '15 at 03:49
  • Meredith, are your 50 different detail pages structurally different, or are they really just different permutations of the same style of detail page (or a some limited number of types of detail pages), just showing different detail data? Usually you'd see a few types of detail scenes, and it's only a question of what data is shown in that destination scene. It's hard to answer the question without a sense of the nature of variation amongst these detail scenes. – Rob Aug 09 '15 at 03:55
  • @Rob, it's the exact same format for each detail page. basically a title label, a phone number, and a mailing address – Meredith Caveney Aug 09 '15 at 12:12
  • OK, then we're talking about a single destination view controller, just showing custom data on the basis of which row you selected. BTW, are these contacts from the user's app's address book, or is this you own app data. There is a slick UI for showing contacts (the AddressBookUI framework), but that is intended for when using the device's internal address books, not just random app data. – Rob Aug 09 '15 at 12:29
  • It would be from my own data. The app is sort of a phone book for local police, so if you need a group to help for a certain situation, you can find the contact information. It's a little confusing because it seems everyone does it differently, and the programming/storyboard get a little mixed up for me – Meredith Caveney Aug 09 '15 at 13:24

2 Answers2

0

If using storyboards, the process is fairly simple.

First, I'd suggest dragging a prototype "table view cell" on to your table views. You can then control-drag from that prototype cell to your destination scene to add a segue between the cell and the next scene:

enter image description here

Make sure to select that prototype cell and set its storyboard identifier (I used "Cell"). You will need to reference that storyboard identifier, as shown in my code sample below. I also configured appearance related things (like the disclosure indicator) right in that cell prototype in IB so I don't have to worry about doing that in code and I can see what the UI will look like right in IB.

Now you can go to the table view controller and (a) simplify cellForRowAtIndexPath (because you don't need that logic about if (cell == nil) ... when using cell prototypes); but also implement a prepareForSegue to pass the data to the destination scene:

//  SecondViewController.m

#import "SecondViewController.h"
#import "DetailsViewController.h"

@interface SecondViewController ()
@property (nonatomic, strong) NSArray *tableData;
@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableData = @[@"Carter", @"Greene", @"Hancock", @"Hawkins", @"Johnson", @"Sullivan", @"Unicoi", @"Washington"];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.destinationViewController isKindOfClass:[DetailsViewController class]]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSString *name = self.tableData[indexPath.row];
        [(DetailsViewController *)segue.destinationViewController setName:name];
    }
}

- (IBAction)unwindToTableView:(UIStoryboardSegue *)segue {
    // this is intentionally blank; but needed if we want to unwind back here
}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.tableData.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    cell.textLabel.text = self.tableData[indexPath.row];

    return cell;
}

@end

Obviously, this assumes that you created a DetailsViewController and specified it as the destination scene's base class, and then create properties for any values you want to pass to this destination scene:

//  DetailsViewController.h

#import <UIKit/UIKit.h>

@interface DetailsViewController : UIViewController

@property (nonatomic, copy) NSString *name;

@end

And this destination scene would then take the name value passed to it and fill in the UILabel:

//  DetailsViewController.m

#import "DetailsViewController.h"

@interface DetailsViewController ()

@property (weak, nonatomic) IBOutlet UILabel *nameLabel;

@end

@implementation DetailsViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.nameLabel.text = self.name;
}

@end

Frankly, this process will undoubtedly be described more clearly in any UITableView tutorial includes a discussion of "cell prototypes" (your code sample suggests you were using an older tutorial that predates cell prototypes).

Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

I think the relationship between the code and the storyboard is as following:

  1. Code implement the function of the application.
  2. Storyboard contains many scenes, these scenes implement the User interface, including data presentation, data input, data output.
  3. Code read data from these scenes and output the result to the scenes.
  4. Code is internal logic function entities and the storyboard the the User Interface presentation.
jrbedard
  • 3,662
  • 5
  • 30
  • 34
Leemboy
  • 31
  • 1
  • 2