So I have a custom UITableViewCell:
TestTableViewCell.h
#import <UIKit/UIKit.h>
#interface TestTableViewCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UILabel *testCellLabel;
#end
TestTabelViewCell.m
#import "TestTableViewCell.h"
#implementation TestTableViewCell
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
_testCellLabel = [[UILabel alloc] init];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
And then I have view controller with a table view that uses the custom table view cell. However this issue is that I don't want to use dequeueReusableCellWithIdentifier within the cellForRowAtIndexPath. I instead want to have an array of cells.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#end
ViewController.m
#import "ViewController.h"
#import "TestTableViewCell.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (strong, nonatomic) NSArray *myTableViewCells;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSArray *)myTableViewCells {
TestTableViewCell *cell1 = [[TestTableViewCell alloc] init];
cell1.testCellLabel.text = #"one";
cell1.backgroundColor = [UIColor blueColor];
TestTableViewCell *cell2 = [[TestTableViewCell alloc] init];
cell2.testCellLabel.text = #"two";
cell1.backgroundColor = [UIColor greenColor];
if (!_myTableViewCells) {
_myTableViewCells = #[cell1, cell2];
}
return _myTableViewCells;
}
#pragma mark - UITableView delegate functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.myTableViewCells.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TestTableViewCell *cell = self.myTableViewCells[indexPath.row];
return cell;
}
#end
The problem is that there is no testCellLabel appearing in the table view cell. I know the cells are there, because I set their background colour.
After talking to a few people, apparently I need to do some sort of loading from the XIB or the NIB for the UI to load properly? Even though the label is defined in the cell in the storyboard.
I know this is going against the norm and that Apple really wants you to use dequeueReusableCellWithIdentifier, but I know it won't work in the situation I need it in. I have done the reading on that much so please don't just tell me to use it. This code example is just very basic for example sake and ease of use.
Any help would be greatly appreciated.
TestTableViewCell *cell1 = [[TestTableViewCell alloc] init];
Creates a new TestTableViewCell object and does not instantiate it from the storyboard like you're thinking it does. Therefor all outlets created will be nil and simply not show up. The fact that you can set the background colour is not evidence that your implementation works.
You need to use dequeueReusableCellWithIdentifier. You say that it doesn't work for your problem.. show me how it doesn't work and I will tell you why you're wrong.
Edit
I see in your comments you say your cell needs a custom setter. Well, when you use dequeueReusableCellWithIdentifier you can do all setup work in awakeFromNib (If using a xib file) OR initWithCoder if you are using the storyboard.
You can create cell without dequeueResableCellWithIdentifer.
[[UITableViewCell alloc]initWithStyle:<#UITableCellStyle#> resueIdentifier:<#(nullable *NSString)#>]
Related
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.
If anyone can help me individually add details to each table view cell in the most painless way possible, I would appreciate it. Thanks!
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:
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).
I think the relationship between the code and the storyboard is as following:
Code implement the function of the application.
Storyboard contains many scenes, these scenes implement the User interface, including data presentation, data input, data output.
Code read data from these scenes and output the result to the scenes.
Code is internal logic function entities and the storyboard the the User Interface presentation.
I have 2 UIViewControllers, the 2 ones are containing EXACTLY the SAME UITableView(with its custom cells and delegate methods).
My question is their any way to "centralize" the UITableView UI and code(datasource and delegates), so that I just have to modify in one file instead of 2 .
following up on my comment, the table view in the xib in your father vc and the delegate methods in your father vc are just in the same place because you chose it to be like that, the table view and the delegate methods are actually quite detached.
so create a new object, say FatherTableController which implements UITableViewDatasource and UITabelViewDelegate and copy those methods out of your FatherViewController into this FatherTableController
now in your FatherViewController, go like
FatherTableController tableController = [FatherTableController new]; //should be a property or a singleton
self.tableview.delegate = tableController;
self.tableview.datasource = tableController;
now you can do that in both your separate vc's that use the same table, and even use the exact same table contoller between the two views if you share it in some way (possibly via a singleton pattern, which can be useful for sharing state between the two view controllers)
Solution:
#interface FatherViewController : UIViewController <UITableViewDataSource,UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *parentTableView;
#implementation FatherViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.parentTableView.delegate=self;
self.parentTableView.dataSource=self;
}
//declare the delegate / datasource methods
--------------------- CHILD VIEW CONTROLLER ---------------------
#interface ViewController : FatherViewController
#property (strong, nonatomic) IBOutlet UITableView *tableView;
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate=self;
self.tableView.dataSource=self;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [super numberOfSectionsInTableView:tableView];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [super tableView:tableView numberOfRowsInSection:section];
}
I am new at Objective-C, and I'm trying to understand delegates. I have searched and read a lot, but nothing is really helping me understand. I think that best way to understand this might be asking a question with a sample app.
I'm trying to create a grade calculator application to test my skills. Here are my files:
mainTableViewController.h
#import <UIKit/UIKit.h>
#interface mainTableViewController : UITableViewController
#end
mainTableViewController.m
#import "mainTableViewController.h"
#import "addLectureViewController.h"
#interface mainTableViewController ()
#end
#implementation anaTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
[lectureName count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
#end
addLectureViewController.h
#import <UIKit/UIKit.h>
#interface addLectureViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *lectureNameTextField;
- (IBAction)addButtonPressed:(id)sender;
#property NSMutableArray *lectureName;
#property NSObject *lecture;
#end
addLectureViewController.m
#import "addLectureViewController.h"
#interface addLectureViewController ()
#end
#implementation addLectureViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_lectureName = [[NSMutableArray alloc] init];
_lecture = [[NSObject alloc] init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (IBAction)addButtonPressed:(id)sender {
_lecture = _lectureNameTextField.text;
[_lectureName addObject:_lecture];
NSLog(#"%#",_lectureName);
}
#end
Everything is okay so far. But when i try to use the _lectureName NSMutableArray at mainTableViewController.m, I can't see the array.
I know the codes for printing the array in tableView. I know they are not at there right now. I just don't understand implement delegate codes to my code.
If You want to display something on the rows of the table, You can take an NSArray and you have to return the count of the array in the delegate method:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return array.count;
}
Otherwise, table will not display any elements. And delegate method cellForRowAtIndexPath will only be called if you are returning a particular array count of number count in your numberOfRowsInSection method.
You can take reference from these links to understand delegates:
http://www.tutorialspoint.com/ios/ios_delegates.htm
How do I set up a simple delegate to communicate between two view controllers?
http://code.tutsplus.com/tutorials/ios-sdk-custom-delegates--mobile-10848
But in the case of tableView, the delegate methods are internally defined and triggered internally. We just need to set those delegates to the controller which acts as a listener.
The below code might have syntax errors but they can provide a summary of delegates for this code.
Make the following changes :-
mainTableViewController.h
#import <UIKit/UIKit.h>
#interface mainTableViewController : UITableViewController
#property(strong, nonatomic) NSMutableArray *lectureName
#end
Synthesize the property lectureName in mainTableViewController.m
Then make the following changes in addLectureViewController.h
#import <UIKit/UIKit.h>
#import "mainTableViewController.h"
#interface addLectureViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *lectureNameTextField;
- (IBAction)addButtonPressed:(id)sender;
#property(weak, nonatomic) id<mainTableViewController> delegate;
#property NSMutableArray *lectureName;
#property NSObject *lecture;
#end
Synthesize the property delegate in addLectureViewController.m
Then make the following change :-
- (IBAction)addButtonPressed:(id)sender {
_lecture = _lectureNameTextField.text;
[_lectureName addObject:_lecture];
NSLog(#"%#",_lectureName);
delegate.lectureName=_lectureName;
}
Assuming that you are pushing addLectureViewController from mainTableViewController, also include the following code in prepareForSegue of mainTableViewController (or whatever method in which you are pushing addLectureViewController). :-
addLectureViewController *vc=[[addLectureViewController alloc] init];
vc.delegate=self;
// Push vc
The above code actually creates a weak property of type id<mainTableViewController> called delegate (weak in order to prevent reference cycles). This way, addLectureViewController can update mainTableViewController's property.
Points:
Why is the class in mainTableViewController.m named anaTableViewController. It should be mainTableViewController (almost always, until you get more advanced).
mainTableViewController and addLectureViewController should start with capital letters.
The only way for mainTableViewController to access lecture is through a addLectureViewController object, e.g.
addLectureViewController *alvc = // *something* here
NSArray *localLecture = [alvc lecture];
Figure out how you have access to an addLectureViewController and you will have solved your problem.
I am trying to implement the concept shown in this example project. My goal is to separate my view controller class and the datasource protocol. Instead of implementing the table view datasource methods in my table view controller class, I try to put it in its own class, and in my view controller, I only call this method to set up my table view:
- (void)setupTableView
{
void (^configureCell)(JVRTodoItemCell *, JVRTodoItem *) = ^(JVRTodoItemCell *cell, JVRTodoItem *todoItem)
{
[cell configureForTodoItem:todoItem];
};
NSArray *todoItems = currentUser.todoItems;
self.todoArrayDataSource = [[JVRArrayDataSource alloc] initWithItems:todoItems withCellIdentifier:TodoCellIdentifier withConfigureCellBlock:configureCell];
self.tableView.dataSource = self.todoArrayDataSource;
[self.tableView registerClass:[JVRTodoItemCell class] forCellReuseIdentifier:TodoCellIdentifier];
}
The data source is separated into its own class:
#interface JVRArrayDataSource ()
#property (copy,nonatomic) NSArray *items;
#property (copy,nonatomic) NSString *cellIdentifier;
#property (copy,nonatomic) void (^configureCellBlock)(id item, id cell);
#end
#implementation JVRArrayDataSource
...
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier forIndexPath:indexPath];
id item = [self itemAtIndexPath:indexPath];
self.configureCellBlock(cell,item);
return cell;
}
The interesting part is that creating the cell based on the identifier (using dequeueReusableCellWithIdentifier:forIndexPath:) seems to be successful, because the correct cell gets allocated, but its labels remain nil. I try setting up my cell using the following method, but the values remain nil (aTodoItem has valid properties):
- (void)configureForTodoItem:(JVRTodoItem *)aTodoItem
{
self.todoItemTitle.text = aTodoItem.title;
self.todoItemPriority.text = [NSString stringWithFormat:#"%d", aTodoItem.priority];
}
I am trying to figure out what could possibly be missing here, but so far, I haven't managed to fix the issue yet, and I'm starting to lose hope. Any help would be appreciated.
UPDATE:
To make it clear, the issue is shown on this picture.
It seems that the cells get created, but its labels don't.
If all you want to do is separate your tableview datasource delegate from the view controller you can create a separate class called TableViewDataSource. Within that class you can manage the datasources and their table view cells; configuring the them in your view controller, but letting the TableViewDataSource manage them.
TDSTableViewDataSource.h
#import <Foundation/Foundation.h>
#protocol TDSTableViewDataSourceDelegate <NSObject>
- (NSString *)fetchCellIdentifierForObject:(id)object;
- (UITableViewCell *)configureCell:(UITableViewCell *)cell usingObject:(id)item;
#end
#interface TDSTableViewDataSource : NSObject <UITableViewDataSource>
#property (strong, nonatomic) NSArray *items;
#property (strong, nonatomic) id<TDSTableViewDataSourceDelegate> delegate;
#end
TableViewDataSource.m
#import "TDSTableViewDataSource.h"
#implementation TDSTableViewDataSource
- (NSArray *)items {
if (!_items) _items = [[NSArray alloc] init];
return _items;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if ([self.items count]) {
return [self.items count];
} else {
NSLog(#"numberOfSectionsInTableView could not be determined. self.items is nil or empty.");
return 0;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if ([self.items count]) {
return [self.items count];
} else {
NSLog(#"numberOfRowsInSection could not be determined. self.items contains fewer section requested does not contain any items.");
return 0;
}
}
/*
Single dimension Array of items belonging to a UITableView section
The method checks if the cell implements the HZConfigureTableViewCellDelegate, which is required.
The delegate should be the View Controller.
*/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
id obj = [self.items objectAtIndex:indexPath.row];
UITableViewCell *cell = nil;
if ([self.delegate conformsToProtocol:#protocol(TDSTableViewDataSourceDelegate)]) {
NSString *cellIdentifier = [self.delegate fetchCellIdentifierForObject:obj];
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (obj)
cell = [self.delegate configureCell:cell usingObject:obj];
}
return cell;
}
#end
This class and the protocol will essentially allow you to fetch and configure UITableViewCell's and not have to implement the protocols into your View Controller.
Inside your view controller, you create a datasource property using the protocol above.
#import "TDSViewController.h"
#import "TDSTableViewDataSource.h"
#interface TDSViewController () <UITableViewDelegate, TDSTableViewDataSourceDelegate>
#property (strong, nonatomic) TDSTableViewDataSource *dataSource; // UITableView data source.
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
#implementation TDSViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.dataSource = self.dataSource;
self.dataSource.delegate = self;
}
#pragma mark - UITableView methods
-(NSString *)fetchCellIdentifierForObject:(id)object {
// Check if this is an event or a Reminder class.
if ([object isKindOfClass:[UITableViewCell class]]) {
// Return the cell identifier for this particular cell.
return #"com.myapp.defaultcell";
}
return #"blankcell";
}
- (UITableViewCell *)configureCell:(UITableViewCell *)cell usingObject:(id)item {
UITableViewCell *configuredCell = cell;
// Check if this is an event or a reminder.
if ([item isKindOfClass:[UITableViewCell class]]) {
// Configure the cell to present what data we want here...
}
return configuredCell;
}
#end
This is a complete example project. You can use this to configure any kind of cell you want, without having to add the datasource methods to your view controllers.
The view controller is used by the ConfigureTableViewCellDelegate protocol to configure the UITableViewCell's and use them in the Table View. Since the code is segregated now, the TableViewDataSource class now handles presenting the data to the table view. The View Controller is simply used to configure the cell's. This allows you to use custom UITableViewCells' on each ViewController if you want, and not have to deal with implementing the data sources each time.
UPDATED
Provided a better example, a complete project template.
In the ViewDidLoad register the nib, it fix the problem :)
-(void)viewDidLoad
{
[self.leftTableView registerNib:[UINib nibWithNibName:NIB_FILE bundle:nil] forCellReuseIdentifier:CELL_IDENTIFIER];
}
After hours of digging, I've managed to solve the issue (for now), by changing my custom cell's outlets to strong properties, and initializing them in the cell's init method:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.todoItemTitle = [[UILabel alloc] init];
self.todoItemPriority = [[UILabel alloc] init];
}
return self;
}
This is very strange, since I thought that creating my views in storyboard, this should be automatically taken care of, and I've never had to do this manually before.
I am learning how to use storyboards by making a very simple app. On the main view controller (InfoViewController), I have a textField by the name: nameField. After entering text in this field, when I enter the save button, the text should should get appended to the array (list) (declared in TableViewController) and be displayed on the table in TableViewController.
Also, the segue identifier is: GoToTableViewController.
However, the text does not get passed from nameField to the list (array). At first, I assumed that I was making some mistake with the textField. So I replaced it with a static text. But that did not help either. Then I checked if the string has been added to the array by using NSLog() , but every time I get Null. From my understanding, the list (array) is not created until TableViewController is loaded. For that reason, I alloc and init list in InfoViewController. But it does not help.
Can somebody please help me find out the mistake that I am making?
Thanks!
Relevant sections of my code are as follows:
InfoViewController.h
#import <UIKit/UIKit.h>
#class TableViewController;
#interface InfoViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *nameField;
#property (strong, nonatomic) TableViewController *tableViewController;
#end
InfoViewController.m
#import "InfoViewController.h"
#import "TableViewController.h"
#implementation InfoViewController
#synthesize nameField;
#synthesize tableViewController;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
tableViewController = [[TableViewController alloc] init];
tableViewController.list = [[NSMutableArray alloc] init];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqual:#"GoToTableViewController"])
{
/* Pass data to list and then reloadTable data */
tableViewController = segue.destinationViewController;
tableViewController.infoViewController = self;
// (*) [tableViewController.list addObject:nameField.text];
// (*) [tableViewController.list addObject:#"Hi!"];
[tableViewController.list insertObject:#"Hi" atIndex:0];
// (**) NSLog(#"%#", [tableViewController.list objectAtIndex:0]);
[tableViewController.tableView reloadData];
}
}
#end
( * ) I inserted these statements to see if I was making a mistake with using the value in nameField.
( ** ) This statement is meant to check the value inserted in the array.
TableViewController.h
#import <UIKit/UIKit.h>
#class InfoViewController;
#interface TableViewController : UITableViewController
#property (nonatomic, strong) NSMutableArray *list;
#property (strong, nonatomic) InfoViewController *infoViewController;
#end
TableViewController.m
#import "TableViewController.h"
#import "InfoViewController.h"
#implementation TableViewController
#synthesize list;
#synthesize infoViewController;
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
list = [[NSMutableArray alloc] init];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{ return 1; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{ return list.count; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [list objectAtIndex:indexPath.row];
return cell;
}
#end
Reload the table in viewWillAppear method of tableViewController:
[tableViewController.tableView reloadData];