Reputation: 642
I have an app for iPhone with a Tableview, whose data comes from CoreData.
The same data are also displayed in a watch app:
If I add a row from the iPhone app:
and I reload data in the Watch app:
I see the old rows empty!
If the stop the watch app and I start it again, everything appears correctly!
This is the code to fill the Tableview in the watch app
-(void)awakeWithContext:(id)context{
[super awakeWithContext:context];
[self loadTable];
}
-(void)loadTable{
NSLog(@"loadTableData");
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Data"];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Data"
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortByDate = [[NSSortDescriptor alloc] initWithKey:@"sortedDateAndTime" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortByDate, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
self.watchMArray = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
// [self.watchTableView setRowTypes:self.watchMArray];
[self.watchTableView setNumberOfRows:self.watchMArray.count withRowType:@"data"];
for (NSInteger i = 0; i < self.watchMArray.count; i++)
{
WatchTableCell *cell = [self.watchTableView rowControllerAtIndex:i];
NSManagedObject *data = [self.watchMArray objectAtIndex:i];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
UIImage *foto =[self loadImageFromData:[data valueForKey:@"imageData"]];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
[cell.watchImage setImage:foto];
[cell.watchDate setText:[NSString stringWithFormat:@"%@", [data valueForKey:@"dataEOra"] ]];
});
});
}
}
This is the code I am currently using to reload it:
- (IBAction)reloadTable {
[self loadTable];
}
Where am I wrong?
Upvotes: 23
Views: 10720
Reputation: 588
For watchOS 5.1, iOS 12.1 it only worked if I added the setNumberOfRows:withRowType:
in didAppear
method.
Using the awake(withContext:)
or willActivate
did not work for me. The first 4 rows were blank.
Upvotes: 1
Reputation: 419
I do believe you have to do two things simultaneously in order to achieve same result of tableview.reloadData() iOS function , so to reload a table in the watch with newly data do the following : 1-call table method :setNumberOfRows 2-loop through the rows refreshing values .
vacationList.setNumberOfRows(dict.count, withRowType: "vacationRow")
for index in 0..<vacationList.numberOfRows {
if let controller = vacationList.rowControllerAtIndex(index) as? VacationRowcontroller {
controller.vacation = dict.objectForKey("\(index)") as? NSDictionary
}
}
hint : dict = dictionary of newly reloaded data from backend.
Upvotes: 0
Reputation: 911
I've discovered that calling setNumberOfRows:rowType does not refresh the table unless you call it from the willActivate method. I had a delegate method that I was calling from a modal controller which would fetch a new set of records from the parent app and then reload the table. Even though printing out numberOfRows showed the new number of rows that I set, visually the existing rows were still displayed on screen. It was only after I set a flag in my delegate method and then in willActivate checked that flag and only then reloaded the table, did it refresh the display.
Upvotes: 4
Reputation: 719
In the link @leolobato posted, there is actually a workaround. It did solve my problem.
https://devforums.apple.com/message/1098875#1098875
when you change your rows just set them to =@"" first.
For example, if your row has a row.Label and you are changing it, do row.Label.text = @"" then again right after row.Label.text =@"[Actual text]"
Upvotes: 11
Reputation: 20177
To reload the data, change your IBAction to:
- (IBAction)reloadTable {
[self.watchTableView setNumberOfRows:self.watchMArray.count withRowType:@"data"];
}
From Apple's developer documentation on WKInterfaceTable:
This method removes any existing rows from the table and configures a new set of rows based on the information in the numberOfRows and rowType parameters.
Given you are using setNumberOfRows:withRowType:
in your original code, I have used that here. The method setRowTypes:
also achieves the same effect.
Upvotes: 1
Reputation: 864
Calling the setRowTypes:
or setNumberOfRows:withRowType:
method.
Below is a statement from the developer document, I believe this will work.
When you want to update the contents of a table, call setRowTypes: or setNumberOfRows:withRowType: again with the new row type information. Calling these methods again forces the table to discard the old rows and create new ones. To insert new rows without removing the old ones, use the insertRowsAtIndexes:withRowType: method.
Upvotes: 6