23

I have an app for iPhone with a Tableview, whose data comes from CoreData.

enter image description here

The same data are also displayed in a watch app:

enter image description here

If I add a row from the iPhone app:

enter image description here

and I reload data in the Watch app:

enter image description here

I see the old rows empty!

enter image description here

If the stop the watch app and I start it again, everything appears correctly!

enter image description here

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?

Duncan Babbage
  • 19,972
  • 4
  • 56
  • 93
Ragazzetto
  • 622
  • 1
  • 8
  • 18

6 Answers6

11

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]"

Bonan
  • 709
  • 4
  • 18
6

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.

Link to document

Jay
  • 856
  • 7
  • 17
  • as you can see from the code in the method loadTable there is already a method call [self.watchTableView setNumberOfRows: self.watchMArray.count withRowType: @ "date"]; – Ragazzetto Jan 20 '15 at 15:11
  • Technically it should work with only single line of code, mentioning the setRowTypes. I haven't tried, but I have read the document, thats why I send you. – Jay Jan 21 '15 at 05:14
  • Thank you @JayahariV , I've use the Duncan code but in my case the change of the code has not solved the problem !! Now all rows are empty :-( – Ragazzetto Jan 21 '15 at 18:21
  • Is this still a bug in the current version after beta? I log what text I'm using in the labels when I do a reload, but its not changing what is in the table. – Jason Hocker May 16 '15 at 05:46
4

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.

Tap Forms
  • 912
  • 8
  • 16
1

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.

Duncan Babbage
  • 19,972
  • 4
  • 56
  • 93
  • Thanks for the suggestion Duncan, but in my case the change of the code has not solved the problem !! Now all rows are empty:-( – Ragazzetto Jan 20 '15 at 21:41
  • Yeah ;-) The strange thing is that the detailview works perfectly, only the data of the table are missing :-( – Ragazzetto Jan 20 '15 at 21:54
  • Small update, is displayed in the table only the last item in that array – Ragazzetto Jan 20 '15 at 22:10
  • I'll add that I am seeing some strange behavior with watchkit tables. I am calling setNumberOfRows:withRowType using an NSTimer and the reloaded table is not rendering correctly. The row label text is coming from the nib and not my code. So it could be watchkit code and not yours. – jkingyens Jan 23 '15 at 21:06
  • Are you using an NSTimer to poll for changes in your underlying dataset? – Duncan Babbage Jan 23 '15 at 21:08
  • no NSTimer @DuncanBabbage ! I manually update the table in watch extension after I added the object in the iPhone App ! – Ragazzetto Jan 24 '15 at 09:47
  • The strange thing is that if I put a NSLog to see the table data in console would seem that everything is right ! [cell.watchImage setImage:foto]; NSLog(@"immagine %@",cell.watchImage); 2015-01-24 11:20:56.196 WatchKit Extension[9555:291876] immagine – Ragazzetto Jan 24 '15 at 10:38
  • @jkingyens so do you think is a WatchKit bug ? – Ragazzetto Jan 24 '15 at 13:41
  • 1
    @Ragazzetto I think it's likely there are still bugs in the SDK, yes. – jkingyens Jan 24 '15 at 18:11
1

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.

Andrei Marcu
  • 588
  • 6
  • 9
0

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.

IsPha
  • 389
  • 4
  • 9