Search code examples
iphoneobjective-cuitableviewuistoryboardsegue

Passing Data from Dynamic tableView to Static TableView


Hi Let me try to clarify my issue. I have two TableViews, one is static and the other is dynamic. The static= RootVC and Dynamic=FirstVC. In FirstVC i have data that I want to select,save and pass the saved data to a UILabel in RootVC. 1)When I run my App data is selected however it is not saved or passed to my rooVC. I was using delegates and was advice not to use "delegate" but use "Blocks". But still i'm facing the same issue. Here is my code:

in rootVC.h
#import <UIKit/UIKit.h>

@interface RootViewController : UITableViewController
{

    NSString *getRepeatLabel;
}
@property (strong, nonatomic) IBOutlet UILabel *repeatLabel;
@property (strong, nonatomic) IBOutlet UILabel *repeatDetail;
@property (nonatomic,strong) NSString *getRepeatLabel;
@end

in my rootVC.m

#import "RootViewController.h"

@interface RootViewController ()

@end

@implementation RootViewController
- (void)viewDidLoad
{
    [super viewDidLoad];

    _repeatLabel.text = @"Repeat";
    _repeatDetail.text = getRepeatLabel;


}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UIViewController *destinationController = segue.destinationViewController;
    if( [destinationController isKindOfClass:[FirstViewController class]] )
    {
        [(FirstViewController *)destinationController setCompletionBlock:^(NSString *getRepeatLabel;)
         {

             // do something here with your string // maybe you must reload your table // it depends on where your returning data needs to display    <--------Not sure what to do here
             // NSDateFormatter*dateFormatter = [[NSDateFormatter alloc]init];
             //    NSArray*days = [dateFormatter shortWeekdaySymbols];  <------Here I would like when data is selected to show days in short symbol
             NSLog (@"The selected day/s is %@", getRepeatLabel); <---nothing displaying on console




         }];
    }
}

@end

in FirstVC.h

#import <UIKit/UIKit.h>
#import "RootViewController.h"
typedef void(^WeekdayCompletionBlock)(NSString *dayName);
@interface FirstViewController : UITableViewController
{
    NSString *dayName;
}


@property (nonatomic, strong) WeekdayCompletionBlock completionBlock;
@property (nonatomic,strong) NSString *dayName;
- (IBAction)save:(id)sender;
@end

in FirstVC.m

#import "FirstViewController.h"
#import "RootViewController.h"
@interface FirstViewController ()
@end

@implementation FirstViewController
@synthesize completionBlock;
@synthesize dayName;


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // Initialize table data
    completionBlock = [NSArray arrayWithObjects:@"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday", nil];


}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations

    return YES;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [completionBlock count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"RepeatCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];


    }


    cell.textLabel.text = [completionBlock objectAtIndex:indexPath.row];

    return cell;
}




// Called after the user changes the selection.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    NSLog (@"The selected day/s is %@", [completionBlock objectAtIndex:indexPath.row]);


   _getRepeatLabel = completionBlock; //<-----------string from RootVC gives error "undeclared _getRepeatLabel"
}
- (IBAction)save:(id)sender
{
    NSUserDefaults *myNewWeekString = [NSUserDefaults standardUserDefaults];
    [myNewWeekString setObject:completionBlock forKey:@"%@"];
    [myNewWeekString synchronize];
    self.completionBlock(myNewDayOfWeekString) <------error myNewDayOfWeekString undeclared and if i declare it here it complains about incompatibility


}
@end

Solution

  • Your code is a little bit wrong. I think you don't really understand block. You want to pass more than string so the best way to do that is via array. Change block definition to accept array instead of string:

    typedef void(^WeekdayCompletionBlock)(NSArray *dayName);
    

    Change declaration of your property in FirstVC.h to:

    @property (nonatomic, copy) NSArray *completionBlock; //This is your array, you use it as data source, It's not a block
    //Add your block property
    // This is your block property you will use it to pass the data between view controllers
    @property (copy) WeekdayCompletionBlock returnBlock;
    //Add property to keep your selected days
    @property (nonatomic, strong) NSMutableArray *returnArray;
    

    Add this line to viewDidLoad method:

    self.returnArray = [[NSMutableArray alloc] init];
    

    Change your didSelectRowAtIndexPath method in FirstVC.m to:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
    
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
            //remove data from array
            [self.returnArray removeObject:[completionBlock objectAtIndex:indexPath.row]];
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
            //add data to array
            [self.returnArray addObject:[completionBlock objectAtIndex:indexPath.row]];
        }
    
       [tableView deselectRowAtIndexPath:indexPath animated:YES];
    }
    

    In your save: method call block and pass value to rootVC replace line:

    self.completionBlock(myNewDayOfWeekString);
    

    with:

        if (self.returnBlock)
        {
            self.returnBlock(self.returnArray);
        }
        [self.navigationController popViewControllerAnimated:YES];
    

    The last change left to do is set up ablok in your rootVC.m file. Replace line:

    [(FirstViewController *)destinationController setCompletionBlock:
    

    with (nsstring needs to be replaced with nsarray - you pass array with all of the selected data)

    [(FirstViewController *)destinationController setCompletionBlock:^(NSArray *getRepeatLabel)
    

    You set up block not NSArray.

    I don't know what are you trying to do here:

    [myNewWeekString setObject:completionBlock forKey:@"%@"];
    

    You are using %@ as a key. It should be text for example @"MY_KEY_FOR_ACCESING_DAYSOFWEEK". You are saving completionBlock it's all of your days if you want to save just selected days replace it with self.returnArray.

    Hope this help.