Cocoa: Why is my table view blank? - ios

Why is my table view blank? It was fine until I added "initWithStyle"
Here is what it looks like:
And here is what my code looks like:
Here is my .h:
#import <UIKit/UIKit.h>
#interface TableViewController : UITableViewController {
NSMutableArray *jokes;
IBOutlet UITableView *jokeTableView;
}
#property (nonatomic, retain) NSMutableArray *jokes;
#property (retain) UITableView *jokeTableView;
#end
And here is my implementation file:
#import "TableViewController.h"
#import "Joke.h"
#implementation TableViewController
#synthesize jokes;
#synthesize jokeTableView;
- (void)awakeFromNib {
[jokeTableView init];
}
- (id)initWithStyle:(UITableViewStyle)style {
if (self = [super initWithStyle:style]) {
self.jokes = [NSMutableArray arrayWithObjects:
[Joke jokeWithValue:#"If you have five dollars and Chuck Norris has five dollars, Chuck Norris has more money than you"],
[Joke jokeWithValue:#"There is no 'ctrl' button on Chuck Norris's computer. Chuck Norris is always in control."],
[Joke jokeWithValue:#"Apple pays Chuck Norris 99 cents every time he listens to a song."],
[Joke jokeWithValue:#"Chuck Norris can sneeze with his eyes open."],
nil];
self.jokeTableView.rowHeight = 30.0;
// self.jokeTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
self.jokeTableView.sectionHeaderHeight = 0;
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Saying how many sections wanted (Just like in address, where sorts by first name)
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [jokes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Team";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier] autorelease];
}
Joke *j = (Joke *)[jokes objectAtIndex:indexPath.row];
if( j )
cell.text = j.joke;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)dealloc {
[jokes release];
[jokeTableView release];
[super dealloc];
}
#end

If your view controller is being loaded from a nib, you'll need to override the initWithCoder: method, not initWithStyle:.
However, the normal solution would be to add all your custom initialization code in the awakeFromNib: method, this is called after the nib is loaded and all outlets are connected, so it makes a great place to do any initialization you need.
See the Apple docs on awakeFromNib: for details on object instantiation from nibs. Also, if you have access to the 3.0 beta docs, do a search for awakeFromNib:, the updated wording gives a better explanation of which methods are called and when.
P.S. You shouldn't be calling [jokeTableView init] in your code, this will be done automatically when the nib is unpacked.
Edit: Since you are setting properties for your table view from your initialization code, this should definitely be in awakeFromNib:, not initWithCoder: or initWithStyle:.
Looking at the screenshot, you might also want to make sure with Interface Builder that the UITableView is placed correctly in the nib file for your view controller, and that the code (or nib) that creates your view controller is referring to the right nib file - if it were just the data for the table view that had not loaded, you would see gray lines between empty cells, not just blank white space like in that image.

initWithStyle is not the same as initWithCoder. Your constructor probably isn't even getting called.

I don't know if it's the cause of your problem, but that random [jokeTableView init] in awakeFromNib is certainly wrong and could cause problems like this. init should never be called without an attached alloc*, and in this case I doubt either is needed since the table view has presumably already been created elsewhere.
(* The one exception to this rule, obviously, is when you're overriding an init method and calling super.)

Well, if you are initializing this controller using initWithStyle and you previously were calling initWithCoder , that is your problem.
You are loading your self.jokes in initWithCoder. You should move that code to viewDidLoad or to your new initWithStyle method
// move this
self.jokes = [NSMutableArray arrayWithObjects:
[Joke jokeWithValue:#"If you have five dollars and Chuck Norris has five dollars, Chuck Norris has more money than you"],
[Joke jokeWithValue:#"There is no 'ctrl' button on Chuck Norris's computer. Chuck Norris is always in control."],
[Joke jokeWithValue:#"Apple pays Chuck Norris 99 cents every time he listens to a song."],
[Joke jokeWithValue:#"Chuck Norris can sneeze with his eyes open."],
nil];

Get rid of this:
- (void)awakeFromNib {
[jokeTableView init];
}
you're already doing initialization in initWithStyle:

I think the main problem is that you need to replace:
- (id)initWithStyle:(UITableViewStyle)style {
if (self = [super initWithStyle:style]) {
(and the closing bracket)
with
- (void)viewDidLoad {
Also, you shouldn't have to end a NSMutableArray with nil.

Related

UITableViewController Delegate and DataSource method not called

I am quite new in ios dev and i am trying to populate table view using Array of HCPerson class. I am also playing around with bring object created in nib to storyboard by code. But no matter what i do the table doesn't become populated
#import "HCTableViewController.h"
NSString *const HCTableCellNibName=#"HCTableCell";
NSString *const HCCellIdentifier=#"personCell";
#interface HCTableViewController()
#end
#implementation HCTableViewController
-(void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:HCTableCellNibName bundle:nil] forCellReuseIdentifier:HCCellIdentifier];
}
-(NSInteger)tableView:(UITableView*)tableView numberOfRowInSection:(NSInteger)section
{
return self.persons.count;
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell* cell=(UITableViewCell*)[self.tableView dequeueReusableCellWithIdentifier:HCCellIdentifier forIndexPath:indexPath];
HCPerson *person=self.persons[indexPath.row];
[self configureCell:cell forPerson:person];
return cell;
}
-(void)configureCell:(UITableViewCell*)cell forPerson:(HCPerson*)person
{
cell.textLabel.text=person.name;
cell.detailTextLabel.text=[[NSNumberFormatter alloc] stringFromNumber:person.age];
}
#end
//HCPerson
#import "HCPerson.h"
#interface HCPerson()
#end
#implementation HCPerson
+(HCPerson*)personWithName:(NSString*)name age:(NSNumber*)age residence:(NSString*)residence contact:(NSString *)contact
{
HCPerson *newPerson=[[self alloc] init];
newPerson.name=name;
newPerson.age=age;
newPerson.residence=residence;
newPerson.contact=contact;
return newPerson;
}
#end
EDIT: Karthik solved this using UIViewController with outleting TableView from it. But is there any way to call the delegate and datasource method using UITableViewController
ok lets try on your viewDidLoad
-(void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:HCTableCellNibName bundle:nil] forCellReuseIdentifier:HCCellIdentifier];
if ( self.persons.count>0)
{
[self.yourtableview reloadData];
}
else
{
// no data found , put the NSLog and print the count
}
ok choice no-2
try this
UITableViewCell* cell=(UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:HCCellIdentifier forIndexPath:indexPath];
Remove that self because it show be kept of that method. Not your Tableview and also try with different name than tableView because Xcode finds it difficult to select one from them.
Did you add table view controller from storyboard?
If yes, Go to storyborad -> Inspector Area ->File Inspector - add your class name there.
Screenshot attached.

Prototype Cell has blank content on ios 7+

This one is driving me crazy - I don't know what am I missing.
here is my ViewController.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.tableView registerClass:[CurrentMatchCell class] forCellReuseIdentifier:#"CurrentMatchCell"];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"1");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"2");
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"3");
CurrentMatchCell *cell = (CurrentMatchCell *)[tableView dequeueReusableCellWithIdentifier:#"CurrentMatchCell"];
if (cell == nil) {
NSLog(#"XXX");
}
[cell.matchDescription setText: #"Home Team vs Away Team"];
return cell;
}
Here is screenshots from the app.
delegate and datasource are set programmatically.
cell attributes :
And the .h file :
#interface CurrentMatchesViewController : UIViewController <NSFetchedResultsControllerDelegate,UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *tableView;
So, I can see logs 1,2,3 being printed out, cell is not nill but I do not see my content. Why is that?
I only see a number of empty white cells (even if I return 0 or whatever it does show the same every time).
Thanks
If you create your table view and your cell prototypes in a storyboard, the storyboard loader takes care of registering the cell prototypes that you defined in the storyboard. So:
You don't need to call registerClass:forCellReuseIdentifier: again in the code. This will actually mess up your storyboard settings.
You can also use dequeueReusableCellWithIdentifier:forIndexPath: instead of dequeueReusableCellWithIdentifier:. That method always returns a cell, so you don't have to have a nil check.
Edit: If that doesn't do the trick, try calling [self.tableView reloadData] after setting the delegate / data source, or set the delegate and data source in the storyboard.
It is because you're not loading your custom nib. Try this. (Make sure CurrentMatchCell is the name of your xib file).
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UINib *nib = [UINib nibWithNibName:#"CurrentMatchCell" bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier:#"CurrentMatchCell"];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
Edit: based on your comment: Don't register the custom cell class when using a storyboard.... it does that for you and it also sets the delegate. So try removing those lines from the viewdidload.... and second I would try actually making CurrentMatchesViewController a subclass of UITableViewController

How do I add storyboard-based Header and CustomTableCell to a “Search Bar and Search Display Controller”

PRESENTATION
Mine is a simple project: It consists of a NavigationController, ViewController, and a “Search Bar and Search Display Controller”
My .h file is
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate>
#end
and my .m file is
#import "ViewController.h"
#interface ViewController ()
#property(nonatomic,strong)NSMutableArray *data;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
self.data=[[NSMutableArray alloc]init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [_data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Configure the cell.
cell.textLabel.text = [NSString stringWithFormat:#"Row %d", indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"Row %d: %#", indexPath.row, [_data objectAtIndex:indexPath.row]];
return cell;
}
#pragma mark - delegate
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(mockSearch:) userInfo:searchString repeats:NO];
return NO;
}
- (void)mockSearch:(NSTimer*)timer
{
[_data removeAllObjects];
int count = 1 + random() % 20;
for (int i = 0; i < count; i++) {
[_data addObject:timer.userInfo];
}
[self.searchDisplayController.searchResultsTableView reloadData];
}
#end
And that’s the entire program. What does it do? User makes a search and the data is displayed in a TableView (similar to a google search).
PROBLEM
I need to use a CustomTableViewCell for my table. And I need to build the TableViewCell from the storyboard (easy to visualize). I am stuck with the storyboard part. How do I place a TableViewCell on the storyboard without a TableView to place it in? I had an idea, I tried it, but it didn’t work. Here is what I did. I placed a “never-to-be-used” TableViewController in the storyboard whose sole purpose is to hold my CustomTableViewCell. Then in code I subclass TableViewCell and use IBOutlet to link the sub-views of the storyboard TableViewCell to my CustomTableViewCell . And then I used my cell as CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];. This didn’t work. The tableView remained blank. And my guess for the failure is that CustomTableViewCell does not belong to the tableView being dequeued from.
I need the UISearchBar to always stay inside the NavigationBar. But so far self.searchDisplayController.displaysSearchBarInNavigationBar = YES; is not doing it. When I first start the app the searchBar is inside the NavigationBar. But as soon as I click on it, it smacks itself right in the middle of my scene/screen and never leaves.
I need to add a Header to my TableView. Which I thought of doing the same way as the CustomTableViewCell, but with a UIView parent class. But again, the CustomTableViewCell portion failed.
PLEA
Thank you for any help you can provide me.
UPDATE
All I am trying to do is allow my users to launch a server side search and view the results in a tableView. This is such a basic thing, I image many people here have done this a number of times. Being new to iOS, I am stuck. But at this point, I have posted my entire project (anyone can reconstruct it), and I have explained in details all the ways I tried to solve the problem. So if someone has a sample project they don’t mind sharing, it would help very much. Or if you know of a git project please put a link to it. Thanks.
If you want to make a stand-alone view (not in a view controller) in IB, then you should do it in a xib file, not a storyboard. You can have as many storyboard and xib files in an app as you want; they can be mixed freely. To make a new cell in a xib file, just go to New File --> User Interface --> Empty then drag in a UITableViewCell. Add any subviews you want, and in your table view controller (or whatever class is your table view data source), register the xib file with, registerNib:forIdentifier: (usually, you do this in viewDidLoad).

TableViewController Button Connection

Im making a project for school and I'm having trouble with table view controllers, i want to add a button to link it to another page thats really it, So i have a list of 7 table cells which connect to the detail view controller, from there i want to add a button which would link that to another page but each of the 7 table cells need to go to different pages, sorry I'm not very good at explaining things but if any one can help me it would be really appreciated.
TableViewController.m
#import "tableViewController.h"
#import "TableCell.h"
#import "DetailViewController.h"
#interface tableViewController ()
#end
#implementation tableViewController
- (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;
_Title =#[#"Centrum Advance", #"Elite Whey Protein", #"USP LABS Jack3d", #"NitroCore 24", #"PHD Synergy ISO 7", #"REFLEX One Stop", #"MET-Rx G.C.M.O"];
_Images=#[#"1C.jpg",#"2C.jpg",#"3C.jpg",#"4C.jpg",#"5C.jpg",#"6C.jpg",#"mets.jpg",];
_Review=#[#"Not Reviewed",#"'I'm a big fan of whey protein becasue the dosing is simple, easy to consume, and usually a lot cheaper than pills. I use to use the regular old GNC 100% whey protein which was good to take after a workout, but I really wanted more from my supplements. Proto Whey had a lot of great reviews and I have to say, it worked pretty well for me.'",#"'Wow. This stuff is amazing. No fillers, the taste (lemon-lime) isn't overwhelming, and I can work out solid for 1.5 hours and still feel like a beast. I've taken NO-Xplode and Black Powder, and I find that Jack3d provides more energy, while something like Black Powder gives me more pump. This is why I mix a scoop of Black Powder and a scoop of Jack3d and get totally effed at the gym.I've come to notice that if I take jack3d later in the day, it really messes with my sleep, and I contribute that to the DMAA in it, which is a stimulant. I just finished a bottle and I notice my tolerance was going up. On days that I was taking just jack3d, since I like to mix it up, I moved up to 2 scoops towards the end of the bottle. So all in all, awesome for energy in the gym, only somewhat decent regarding pump. But I still give it a solid 9. I have yet to try out 1.M.R, which I will be getting next week, and can find out then which is better for me.BTW I didn't get a 'crash' that so many people speak of, this could be that maybe I am not just prone to the type of thing, and that I work out after I get off work, so 'crashing' really doesn't matter for me.'",#"Not Reviewed",#"'I had the double chocolate flavor and it was the BEST tasting stuff I've ever had. It was so good, sometimes I just took a serviing for breakfast if I was running short on time. The effectiveness was good too, and after finishing a tub of it, I noticed just about all of my lifts increased. I gained some great vascularity in my bi's, and my chest strength exploded. Honestly, for all of you who want to spend a little money and get a nice supplement...this is your winner. I am definitely gonna use this for a while until I get sick of the taste or see a new up-and-coming product. Only reason I give value a 5 is because I paid about $40 for the 2LB tub back in January.'",#"Not Reviewed",#"Not Reviewed",];
_Size=#[#"1.2KG",#"3KG",#"2.7KG",#"3.9KG",#"5KG",#"6.4KG",#"0.5KG",];
_Does=#[#"The perfect whey protein to aid weight loss or pack on lean muscle mass",#"Add some serious muscle to your body without the fat!",#"24g of protein per scoop for just 112 calories and no sugars!",#"Premium Whey Isolate",#"Minimal carbohydrates and fats",#"The Only Way To Enjoy Whey Protein",#"27g of protein with each serving",];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#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 _Title.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
TableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
int row = [indexPath row];
cell.TitleLabel.text = _Title[row];
cell.ThumbImage.image = [UIImage imageNamed:_Images[row]];
cell.Review1.text = _Review[row];
cell.Size1.text = _Size[row];
cell.Does1.text = _Does[row];
return cell;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"ShowDetails"]) {
DetailViewController *detailviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
int row = [myIndexPath row];
detailviewcontroller.DetailModal = #[_Title[row],_Images[row]];
}
}
#end
DetailViewController.m
#import "DetailViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_TitleLabel.text = _DetailModal[0];
_ThumbImage.image = [UIImage imageNamed:_DetailModal [1]];
self.navigationItem.title = _DetailModal[0];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
the table cell.m is empty and the .h is used for the IBOutlets
Create a public #property on the DetailViewController that you can set in prepareForSegue:sender: TableViewController to setup the button's target in each individual DetailViewController.
// DetailViewController.h
#interface DetailViewController
#property NSInteger nextPageId; // or whatever
// TableViewController.m
// prepareForSegue...
detailviewcontroller.nextPageId = myIndexPath.row; // something like this
// DetailViewController.m
// viewDidLoad...
[myButton addTarget:self action:#selector(myButtonHandlerMethod) forControlEvents:UIControlEventTouchUpInside];
-(void)myButtonHandlerMethod {
// code to present the next "page" based on self.nextPageId
}
The method addTarget:action:forControlEvents: sets up another method myButtonHandlerMethod to be called when the user taps the button. If the UIButton is in the DetailViewController Storyboard then create a IBOutlet property and reference the button as self.myButton.

Passing data from a dynamic table to a static table

I'm a newbie in IOS,
I've been strugling with passing data from child to parent tableview. I have defined the parent table view as static, four cells are connected to other table views. These tableviews has data i would like when selected to be passed to my static cell accordingly. I read a lot of solutions about passing data, using delegates and segue but none of them seem to be working for me. i.e. a repeat cell in static table view has two labels and the UILabel Repeat, I don't want that to change and repeatDetail this is the one that when a disclosure indicator is triggered and a new tableview is presented with the data to choose to be able when i click back button to have the seleted data in my repeatDetail Label. My static table is embeded in Navigation controller using storyboard. I would like when data is selected in FirstChildViewController to modify selected data i.e. Monday to Mon in RootViewController. However in my code after selecing data in child checkmark is there but as soon
as I move back to RootVC nothing is showing,and when i go back to Child no selction is howing either.
1. Save the selected Data in Child, only change when there is new selection
2. Use short week names when sending to RootVC
3. repeatDetail to have the selected data
Without writting too much let me show what i have done.
in RootViewController.h // RootViewController is static
#import "FirstChildViewController"
#interface RootViewController: UITableViewController <repeatProtocol> //RootViewController COnfirms to the delegate
#property repeat, repeatDetail;
#end
next on my RootViewController.m
#implementaion RootViewController
#sysnthesis repeat,repeatDetail;
- (void) viewDidload
{
repeat.text = #"Repeat"
repeatDetail= //not show how call this label from 1stViewController
}
-(void) selectedValue:(NSString *)string //protocol method
{
FirstChildViewController *RVC =[[FirstChildViewController alloc] init];
RVC.delegate =self;
[self selectedValue:string]; //This part confuses me, i know i have to implement the delegate method but not sure if i implement it correctly.
}
-(void) didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
in FirstChildViewController.h
#class FirstChildViewController
#protocol repeatProtocol <NSObject>
#required
-(void) selectedValue:(NSString *)string;
#end
#interface FirstChildViewController: UITableViewController
{
NSArray *tableData;
id <repeatProtocol > repeatDelegate;
NSString *selectedDay;
}
#property (retain) id <repeatProtocol> repeatDelegate;
in FirstChildViewController.m
#synthesize tableData;
#synthesize repeatDelegate;
- (void) viewDidLoad
{
[super viewDidLoad]
tableData= [NSArray alloc] initWithArrays:#"Sunday",#"Monday",#"Tuesday",#"Wednesday",#"Thursday",#"Friday",#"Saturday";
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 7;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"RepeatCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"RepeatCell"];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row]//strings from an array here;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = {tableView cellForRowAtIndexPath:indexPath];
cell.accessaryType = UITableViewCellAccessaryCheckMark;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if([self.delegate respondsToSelector:#selector(selectedValue:)])
{
[self.myDelegate selectedValue:selectedDay];
NSLog(#"string passed");
}
[self dismissViewControllerAnimated:YES completion:nil];
NSLog(#"FirstChildViewController dismissed");
}
#end
It's a little hard to sort out what's happening from your description; so I'll restate what I think the issue is.
You have a UITableView that displays something like settings that you which to modify in a series of distal view controllers. But you're unsure of what mechanism to use when returning that data to the static table view. Basically, you want to capture that data when the distal controller finishes. I won't deal with how you're displaying it in the root view controller, because it's unclear from your code sample.
Nonetheless, I'd favor not using a formal delegate protocol at all. It's just one datum going back - so a protocol seems like a wasted formality. I'd use a completion block.
So your FirstViewController interface could look like
typedef void(^WeekdayCompletionBlock)(NSString *dayName);
#interface FirstViewController : UIViewController
#property (nonatomic, strong) WeekdayCompletionBlock completionBlock;
#end
When you instantiate your FirstViewController, just provide it with a completion block. Since I think you are using Storyboards, you'd do this in prepareForSegue: method of your RootViewController.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UIViewController *destinationController = segue.destinationViewController;
if( [destinationController isKindOfClass:[FirstViewController class]] ) {
[(FirstViewController *)destinationController setCompletionBlock:^(NSString *returnString){
// do something here with your string
// maybe you must reload your table
// it depends on where your returning data needs to display
}];
}
}
Finally, you need to execute that block when the user passes control back to the RootViewController. For example, is there a Save button or the like? There you would just execute the completion block, e.g. self.completionBlock(myNewDayOfWeekString)
Alternatively, you can create a global NSString in rootVC.h:
NSString *returnString;
Include rootVC.h in firstVC.h if you haven't already done that. This allows returnString to be accessible from firstVC.m:
#import "rootVC.h"
You can assign returnString in firstVC.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
...
returnString = <selected value>;
}
And show the returnString in rootVC.m below as NSBum pointed out:
-(void) viewDidload
{
repeat.text = #"Repeat";
repeatDetail.text = returnString;
}

Resources