0

I'm new to delegation, so I've been looking for answers, and I've looked at method delegates doesn't get called and Delegate method not being called to see if my answer would be there. I've also looked at How do I set up a simple delegate to communicate between two view controllers? for a brief rundown of delegates and have done my best to follow it correctly. I have been checking my code and I thought I doing it right, but in my debugging, I've learned that I'm clearly not.

What I want to do is reload a tableView from the file "Data.plist" (stored in the Documents directory) when a user segues back to the parent ViewController (the user has just added a new value to the dictionary). The app loads the new entered correctly upon reopening, so I know that file is being saved correctly.

This is my ParentViewController.h file.

#import <UIKit/UIKit.h>
#import "ChildViewController.h"

@interface ParentViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource, ChildViewControllerDelegate>

@end

This is my ParentViewController.m file.

#import "ParentViewController.h"

@interface ParentViewController () 
@end

@implementation ParentViewController
-(void)addEvent {
    NSLog(@"We are before [self loadNewEvent];");
    [self loadNewEvent];
    NSLog(@"We are after [self loadNewEvent];");
}

-(void)loadNewEvent {
    [self.tableView scrollToRowAtIndexPath:0 atScrollPosition:UITableViewScrollPositionNone animated:YES];
    [self.tableView reloadRowsAtIndexPaths:0 withRowAnimation:UITableViewRowAnimationLeft];
    //[self.tableView reloadData];//This doesn't seem to do anything but leave the tableview blank when this line is in viewDidLoad and viewWillAppear.
    NSLog(@"WHY IS THIS NOT WORKING?!?!");
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    //stuff that loads data initially into tableView
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //cell formatting stuff
    return cell;
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"addEvent"]) {
        [(ChildViewController *)[[segue destinationViewController] topViewController] setFilePath:filePath];
        ChildViewController *detailViewController = [[ChildViewController alloc] init];
        [detailViewController setDelegate:self];
        //[self.navigationController pushViewController:detailViewController animated:YES];
    }
}
@end

This is my ChildViewController.h

#import <UIKit/UIKit.h>

@protocol ChildViewControllerDelegate;

@interface ChildViewController : UIViewController
@property (nonatomic, weak) id<ChildViewControllerDelegate> delegate;
- (IBAction)dismissAndSave:(id)sender;//in implementation
- (IBAction)dismissCancel:(id)sender;//in implementation
@end

@protocol ChildViewControllerDelegate <NSObject>
-(void)addEvent;
@end

and finally my ChildViewController.m file.

#import "ChildViewController.h"
@interface ChildViewController ()
@end

@implementation ChildViewController
- (IBAction)dismissAndSave:(id)sender {
    //perform file-saving operations
    if ([self.delegate respondsToSelector:@selector(addEvent)]) {
        [self.delegate addEvent];
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}
@end

I've run through and debugged, and the last point where the ChildViewController is not nil is at the [detailViewController setDelegate:self]; line in the parent's prepareForSegue method.

The reason I knew my delegate methods weren't being called was because NSLog(@"We are before [self loadNewEvent];"); was not happening.

In addition to the method not being called, when I try to do a [self.tableView reloadData]; in the addEvent delegate method, everything appears blank.

Thank you in advance for your help; you are doing a great service to a student who is teaching himself the ways of iOS programming and Objective-C!

Community
  • 1
  • 1
  • is it stepping into the if for respondsToSelector? – Ben Avery Feb 28 '14 at 00:02
  • I have a feeling your "`self.tableview`" IBOutlet property is not connected. Heck, I don't even see it declared in your .h "`@interface`" file. – Michael Dautermann Feb 28 '14 at 00:02
  • @Ben Avery, I just added a `NSLog(@"We are inside dismissAndSave respondsToSelector");` line inside of the if statement, and it didn't print out. That's probably where the issue is. @Michael Dautermann I didn't think I needed one since the information loads on launch without one. If I need one, how do I set it up without breaking my existing tableView? – waterproofpiano Feb 28 '14 at 00:07
  • Just before the if respondsToSelector, is delegate = nil? – Ben Avery Feb 28 '14 at 00:57
  • delegate is set to 0x0 – waterproofpiano Feb 28 '14 at 02:39

2 Answers2

0

Expanding on my comment, I believe you need to declare a tableview property in your .h file:

e.g.

@property (strong) IBOutlet UITableView *myTableView;

which, once connected to the actual table view in your Storyboard or XIB, you can then reference in your .m file like this:

[self.myTableView reloadData];
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • I added both to my code, but I put the `[self.myTableView reloadData];` into my viewWillAppear method but no luck. Did I put it in the wrong method? – waterproofpiano Feb 28 '14 at 00:17
  • did you connect your tableview in your storyboard to your new "`myTableView`" outlet in your view controller? – Michael Dautermann Feb 28 '14 at 00:21
  • Yep. There was a blue box around the whole thing. – waterproofpiano Feb 28 '14 at 00:52
  • oh and you need to set your data source for your tableview object in your storyboard back to your view controller, so it knows where to draw the data from. – Michael Dautermann Feb 28 '14 at 01:07
  • The ParentViewController is currently the dataSource and delegate, and the myTableView is a "Reference Outlet". Still doesn't seem to reload the data. Am I putting the call in the wrong spot or do I have myTableView hooked up to the wrong place? – waterproofpiano Feb 28 '14 at 02:41
  • Another method you are missing is the *required* datasource one named ["`tableView:numberOfRowsInSection:`"](https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDataSource/tableView:numberOfRowsInSection:). Can you implement that? – Michael Dautermann Feb 28 '14 at 03:19
  • I figured the reload issue out. Thanks!! I was putting the line in the viewWillAppear method instead of viewDidAppear. Now I know what the differences are. However, I still don't have the delegation working, but as long as it refreshes, I'm happy. It's probably a more standard practice to use delegation though...so I should still find out why that's not working. – waterproofpiano Feb 28 '14 at 03:30
0

It looks like you're allocating a new view controller, setting its delegate and then don't do anything with it. It'll get dealloc'd once it is out of scope.

[(ChildViewController *)[[segue destinationViewController] topViewController] setFilePath:filePath];
ChildViewController *detailViewController = [[ChildViewController alloc] init];
[detailViewController setDelegate:self];

Try something like this...

ChildViewController * detailViewController = (id)[segue destinationViewController];
[detailViewController setDelegate:self];
Nicholas Hart
  • 1,734
  • 13
  • 22