maxisme
maxisme

Reputation: 4245

Refresh table from another UIViewController

I have two view controllers one of them (ViewController) has a table called tableView.

I would like to refresh this table from my other view controller (pageView).

I have tried this in the pageView:

ViewController*refresh;
[refresh.tableView reloadData];

But this is not working.

The connecting segue between the two view controllers is a push segue

What should I do? Should I do it through a storyboard segue?

Upvotes: 7

Views: 4749

Answers (16)

user2568615
user2568615

Reputation:

/* Add this line in viewDidLoad method in ViewController (by using this line you are adding notification observer to ViewController class) */

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadTableview:) name:@"ReloadTableview" object:nil];

/* Add this method in ViewController class(this method call when you post notification in pageView) */

- (void)reloadTableview:(NSNotification *)notif
{
     [tableView reloadData];
}

/* add this line when/where you want to refresh your (this line post notification which added in ViewController) */

[[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadTableview" object:nil];

Upvotes: 3

Timur Kuchkarov
Timur Kuchkarov

Reputation: 1155

If you have parent-child relationship you can add weak property to child viewcontroller like this

@property (nonatomic, weak) ParentViewController *parentController;

Then when you need to reload table you just call [parentController.tableView reloadData]

Other way would be using NSNotificationCenter. In controller you want to reload table you should subscribe to notification([[NSNotificationCenter defaultCenter] addObserver...]) and implement selector you supply to this method. In another controller you should post notification with that name.

Also you can just refresh on viewWillAppear if it suits your needs.

Upvotes: 1

Wilson L
Wilson L

Reputation: 138

As a make-up answer to emotality's:

If you want to skip the start-up animation, just simply set a bool property in your ClassTwoController to check if it's first time loading this view

ClassTwoController.h:

@property (nonatomic, assign) BOOL notFirstTimeRun;

ClassTwoController.m:

 -(void)viewWillAppear:(BOOL)animated // in .m file
{
    if(self.notFirstTimeRun) {
        [self.tableView reloadData];
    } else {
         [self playStartUpAnime];
    }
}

 -(void)playStartUpAnimation // in .m file
{
    //Place your codes for animation here
}

in your ClassOneController.m initialise it with the check bool:

ClassTwoController *viewController = [[ClassTwoController alloc] init];
viewController.notFirstTimeRun = YES;

Upvotes: 1

Asawari
Asawari

Reputation: 54

If second view controller is already loaded then you can use NSNotification in firstviewcontroller. This notification will invoke a method in second view controller. In this method write a code to reload a tableview.

Upvotes: 2

kelin
kelin

Reputation: 11974

I think the problem is that you refresh controller view is not loaded. So, reloadTable message simply goes to nil. You can force a View Controller to load its view by calling view getter:

[viewController view];

So check if your tableView is nil and if it is, initialise it with described method.

Upvotes: 1

Paulo
Paulo

Reputation: 1245

Reloaddata needs to execute within the parentviewcontroller because it invokes the tableview delegate methods to reload the table such as CellForRowAtIndexpath, and many more. This means you need to define a public method in the parentviewcontroller that will contain the reloaddata command and call it from the child view controller.

public Method:

Parentviewcontroller.h

@interface 

 -(void) reloadTable:(id) sender;

parentviewcontroller.m

@implementation

- (void) reloadTable:(id) sender {
   [self.tableview reloaddata];
   return;
 }

childviewcontroller.h

 #import parentviewcontroller.h
  @class parentviewController 
  @interface childviewcontroller :UIViewController (or UITableViewController)

  @property (nonatomic, strong) parentViewController *parent;

childviewController.m

@implementation  
 @synthesize parent; 

 /*  Note the parent instance is passed from the parent to the child view controller,      
 it is not allocated and initialised in the child controller -  many ways to do this 
 depending on coding style  */

/* after updating the data */   

 [parent reloadTable];

Upvotes: 1

instaable
instaable

Reputation: 3509

In case you have tried all the answers, make sure that before reloading the tableView, the dataSource is actually updated with new/additional/ content.

Upvotes: 1

user3279053
user3279053

Reputation: 187

Use NSnotification center add observer in that view controller and write method for reload table. [self.tableView reloadData]; And from current view post notify that observer.

Upvotes: 1

Rajesh
Rajesh

Reputation: 10424

ViewController*refresh;
[refresh.tableView reloadData];

By seeing the above code you are not assigning your ViewController instance to refresh. When executing reloadData() your refresh will be nil so obviously it won't react to any action.

ViewController*refresh = originalInstance; //assign your original instance here
    [refresh.tableView reloadData];

this would work and the main point to be noted here is your refresh viewcontroller should be the top most instance in stack because any UI operation should happen in main thread.

Upvotes: 1

emotality
emotality

Reputation: 13035

Option 1

@Class2

@property (nonatomic) BOOL shouldRefresh; // in .h file

- (void)viewWillAppear:(BOOL)animated // in .m file
{
    [super viewWillAppear:animated];
    if (_shouldRefresh) [self.tableView reloadData];
}

@Class1

// Add this in any method where you want it to refresh and push to view
ClassTwoController *viewController = [[ClassTwoController alloc] init];
[viewController setShouldRefresh:YES];
[self.navigationController pushViewController:viewController animated:YES];

*UPDATE:

Option 2

@Class 2

// Add this line in viewDidLoad in same class you want the tableView to refresh
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshTableWithNotification:) name:@"RefreshTable" object:nil];

// Add this method just beneath viewDidLoad:
- (void)refreshTableWithNotification:(NSNotification *)notification
{
    [self.tableView reloadData];
}

@Class1

// Call this when ever you want to refresh the tableView in Class2
[[NSNotificationCenter defaultCenter] postNotificationName:@"RefreshTable" object:nil userInfo:nil];

Upvotes: 20

Neprocker
Neprocker

Reputation: 99

In your pageView create a method

-(void) reloadVCController{

  ViewController*vc=[[ViewController alloc]init]];
    [vc.tableview reloadData;
}

And use it where you want to call it

[self reloadVCController];

Upvotes: 1

user2779060
user2779060

Reputation: 23

You can check the adress of viewcontroller.tableview and refresh.tableView and i think they would be not the same; you can make singleton for viewcontroller and then invoke for example

viewcontroller *vc = [viewcontroller sharedInstance];
[[vc tableview] reloadData];

Upvotes: 1

user3732880
user3732880

Reputation:

In ViewController1 :

> Create property for UITableview with nonatomic and retain
> Now Create table Object.

In ViewController2.m:

ViewController1 *objV1 = [ViewController1 alloc]initWithNibName....];   

[objV1.yourTableView reloadData];

Upvotes: 1

pnavk
pnavk

Reputation: 4632

Okay for sake of example lets call the previous ViewController VC1 and the current ViewController VC2.

So you do a push segue from VC1 to VC2. What you could do is: pass a reference of the TableView to VC2 during the segue. So you would create a public UITableView tblView variable in VC2 and then in VC1 implement the prepareForSegue method

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"Segue_Identifier_From_StoryBoard"])
    {
        // get your destination view controller
        VC2 *vc2 = [segue destinationViewController];

        vc2.tblView = TableView;
    }
}

Then in VC2, you could just call [tblView reloadData];

Just make sure you nil the tblView reference once you are done with VC2.

Upvotes: 1

Nick Frolov
Nick Frolov

Reputation: 1855

Most often this happens because you're not initializing the reference to your second controller properly and it stays nil. Has to be something like this.

@implementation
{
    ViewController *refresh;
}

- (void) openNewController
{
    refresh = [[ViewController alloc] init];
    [self.navigationController pushViewController:refresh animated:true];
}

- (void) refreshNewController 
{
    [refresh.tableView reloadData];
}

@end

Upvotes: 1

spassas
spassas

Reputation: 4818

If I understand correctly, you want to reload a table view that exists in the previous view controller of your navigation stack. If so, you can access it through the navigation controller's viewControllers property.

NSUInteger indexOfTableController = self.navigationController.viewControllers.count - 2;
ViewController *tableController = (ViewController*)[self.navigationController.viewControllers objectAtIndex:indexOfTableController];
[tableController.tableView reloadData];

Upvotes: 1

Related Questions