I'm just going to be crazy. I want to display some attributes from an object in a TableViewController.
To resume :
I've got a first screen with a list of different Aircraft. Each Aircraft is different and get 2 attributes (a name and an identification number). When i click on an aircraft i want to display its informations in a new view controller (here a TableViewController).
The only thing i get is an empty string... I don't understand how to do this.
Here my code for AircraftViewController.h (the list of different aircraft)
#import <UIKit/UIKit.h>
#import "AircraftInfoViewController.h"
#interface AircraftViewController : UITableViewController <AircraftInfoViewControllerDelegate>
#property (nonatomic, strong) NSMutableArray *aircraft;
#end
Here my code for AircraftViewController.m
#import "AircraftViewController.h"
#import "Aircraft.h"
#interface AircraftViewController ()
#end
#implementation AircraftViewController
{
NSString *_info;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.aircraft count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AircraftCell *cell = (AircraftCell *)[tableView dequeueReusableCellWithIdentifier:#"AircraftCell"];
Aircraft *aircraft = (self.aircraft)[indexPath.row];
cell.immatLabel.text = aircraft.immat;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"PickInfo"]) {
AircraftInfoViewController *aircraftInfoViewController = segue.destinationViewController;
aircraftInfoViewController.delegate = self;
aircraftInfoViewController.info = _info;
}
}
- (void)aircraftInfoViewController:(AircraftInfoViewController *)controller didSelectInfo:(NSString *)info
{
_info = info;
Aircraft *aircraft = [[Aircraft alloc] init];
// Here is my problem !
NSLog(#"String is %#", aircraft.name);
[self.navigationController popViewControllerAnimated:YES];
}
#end
Here my Aircraft Object
#import <Foundation/Foundation.h>
#interface Aircraft : NSObject
#property (nonatomic, copy) NSString *name;
#property (nonatomic, copy) NSString *immat;
#end
Here my AircraftInfoViewController.h (where i display info)
#class AircraftInfoViewController;
#protocol AircraftInfoViewControllerDelegate <NSObject>
- (void)aircraftInfoViewController:(AircraftInfoViewController *)controller didSelectInfo:(NSString *)info;
#end
#interface AircraftInfoViewController : UITableViewController
#property (nonatomic, weak) id <AircraftInfoViewControllerDelegate> delegate;
#property (nonatomic, strong) NSString *info;
#end
Here my AircraftInfoViewController.m
#import "AircraftInfoViewController.h"
#interface AircraftInfoViewController ()
#end
#implementation AircraftInfoViewController
{
NSArray *_infos;
NSUInteger _selectedIndex;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_infos = #[#"TEST"];
_selectedIndex = [_infos indexOfObject:self.info];
}
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_infos count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"AircraftCell"];
cell.textLabel.text = _infos[indexPath.row];
if (indexPath.row == _selectedIndex) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (_selectedIndex != NSNotFound) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:
[NSIndexPath indexPathForRow:_selectedIndex inSection:0]];
cell.accessoryType = UITableViewCellAccessoryNone;
}
_selectedIndex = indexPath.row;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSString *info = _infos[indexPath.row];
[self.delegate aircraftInfoViewController:self didSelectInfo:info];
}
#end
Thx for helping...
I don't exactly get your problem, but in your code you are:
//1. creating a new aircraft
Aircraft *aircraft = [[Aircraft alloc] init];
//2. this aircraft object is new and dose not have a name yet as you never assigned a name to it.
//3. this is why your log shows an empty string
NSLog(#"String is %#", aircraft.name);
Looks like you need to print the info:
NSLog(#"String is %#", _info);
But it will be helpful to help you if you could explain what you want to get better.
Related
I am trying to copy the array from tableview controller to view controller. I have checked the code multiple times and it seems to be okay.
//Delegate class
#import <UIKit/UIKit.h>
#protocol Category <NSObject>
#required
-(void) delegateMethodForCategory : (NSMutableArray *) arrayOfCategory;
#end
#interface Categories : UIViewController <UITableViewDelegate,UITableViewDataSource>
#property (nonatomic) id<Category> delegate;
#property (nonatomic,strong) NSArray *sports;
#property (strong, nonatomic) IBOutlet UITableView *tableview;
#property (nonatomic,strong) NSMutableArray *selectedIndexes;
#end
//Delegate methods
#import "Categories.h"
#interface Categories ()
{
NSMutableArray *array ;
}
#end
#implementation Categories
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_sports= [[NSArray alloc] initWithObjects: #"Baseball", #"Soccer", #"Hockey",
#"Other",nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return _sports.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
array = [[NSMutableArray alloc]init];
// Configure the cell...
cell.textLabel.text=[self.sports objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = selectedCell.textLabel.text;
if([tableView cellForRowAtIndexPath:indexPath].accessoryType==UITableViewCellAccessoryNone)
{ [tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;
[array addObject:cellText];
}else if([tableView cellForRowAtIndexPath:indexPath].accessoryType==UITableViewCellAccessoryCheckmark){
[tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryNone;
[array removeObject:cellText];
}
}
- (IBAction)doneButton:(id)sender {
[self.delegate delegateMethodForCategory:array];
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
#import <UIKit/UIKit.h>
#import "Categories.h"
#interface ActivityCreator : UIViewController <UIPopoverPresentationControllerDelegate, Category>
#property (nonatomic) Categories *requestClass;
#property (nonatomic,strong) NSMutableArray *arrayOfSports;
#end
//This class implements delegate
import "ActivityCreator.h"
#interface ActivityCreator ()
#end
#implementation ActivityCreator
- (void)viewDidLoad {
[super viewDidLoad];
[self settingUp];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller{
return UIModalPresentationNone;
}
-(void)settingUp{
_requestClass = [[Categories alloc]init];
self.requestClass.delegate = self;
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"hubabuba"]){
Categories *pop = (Categories *)segue.destinationViewController;
pop.modalPresentationStyle = UIModalPresentationPopover;
pop.popoverPresentationController.delegate = self;
}
}
-(void) delegateMethodForCategory : (NSMutableArray *) arrayOfCategory {
_arrayOfSports = arrayOfCategory;
NSLog(#"%#",_arrayOfSports);
}
Any guidance where I am doing wrong will be of great help. Have been stuck on this for a while.
The delegate method is not being called at all.
Thanks
Set the delegate of Categories class in prepareForSegue method instead of setting in settingUp method.
Write
pop.delegate = self;
In prepareForSegue method.
I have a view controller with a static cell named 'Make' I have two controllers one called "AddCarTableViewController" and "MakeTableViewController" when you click on the static cell named 'Make' it presents the make table view controller where you can select the make, then pops the view controller and am trying to store the selected value in the detailTextLabel of the static cell. here is my code for all the controllers.
The problem I'm having is once I select the make everything happens as it should I even log the selected item and it saves it after popping the view controller, but I can't figure out how to implement selected item into the detailTextLabel. Any help will be much appreciated!
"MakeTableViewController.h"
#import <UIKit/UIKit.h>
#import "AddCarTableViewController.h"
#protocol CarMakeDelegate <NSObject>
- (void)updateCarMake:(NSString *)updateMake;
#end
#interface MakeTableViewController : UITableViewController
#property (nonatomic, strong) NSArray *carMakes;
#property (nonatomic, weak) id <CarMakeDelegate> delegate;
#end
MakeTableViewController.m
#import "MakeTableViewController.h"
#interface MakeTableViewController ()
#end
#implementation MakeTableViewController {
NSIndexPath *oldIndexPath;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.carMakes = [[NSArray alloc] initWithObjects:#"Acura", #"Aston Martin", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.carMakes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [self.carMakes objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
oldIndexPath = indexPath;
NSString *addMake = self.carMakes[indexPath.row];
[self.delegate updateCarMake:addMake];
NSLog(#"%#", addMake );
[[self navigationController] popViewControllerAnimated:YES];
}
#end
AddCarTableViewController.h
#import <UIKit/UIKit.h>
#import "MakeTableViewController.h"
#interface AddCarTableViewController : UITableViewController
#property (strong, nonatomic) NSString *makeName;
#property (weak, nonatomic) IBOutlet UITableViewCell *makeCell;
#end
AddCarTableViewController.m
#import "AddCarTableViewController.h"
#interface AddCarTableViewController ()
#end
#implementation AddCarTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 4;
}
-(void)updateCarMake:(NSString *)updateMake {
self.makeCell.detailTextLabel.text = updateMake;
}
#end
You don't need to use delegate in this case. Just update the underlying data model. and call
[tableview reloadData];
When the makeViewController is popped.
In the AddCarVC's cellForRowAtIndex, add another line to check if current indexPath corresponds to Make cell and if it does update the detailLabel text.
data values i have one text filed and two buttons.One button is save,second button is show.
when click save button data will be Stored in Core-Data and then i click Show button data will be displayed on Console. It gone nice.
But now i want when Click show button data will be displayed on UITableView So Please Give me any idea
Thanks in advanced,
this is my code:-
#import "SetViewController.h"
#import "AppDelegate.h"
#interface SetViewController ()
{
NSMutableArray *array;
}
#end
#implementation SetViewController
#synthesize textField;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)save:(id)sender {
AppDelegate *appD=(AppDelegate *) [[UIApplication sharedApplication]delegate];
NSEntityDescription *entit=[NSEntityDescription insertNewObjectForEntityForName:#"Team" inManagedObjectContext:appD.managedObjectContext];
[entit setValue:textField.text forKey:#"fname"];
NSError *error;
BOOL isSaved=[appD.managedObjectContext save:&error];
NSLog(#"succesfully saved flag: %d",isSaved);
}
- (IBAction)show:(id)sender {
AppDelegate *appDelegat=(AppDelegate*)[[UIApplication sharedApplication]delegate];
NSEntityDescription *entity=[NSEntityDescription entityForName:#"Team" inManagedObjectContext:appDelegat.managedObjectContext];
NSFetchRequest *fetchRr = [[NSFetchRequest alloc]init];
[fetchRr setEntity:entity];
array=[[appDelegat.managedObjectContext executeFetchRequest:fetchRr error:nil]mutableCopy];
NSLog(#"array %#",array);
for (NSManagedObject *obj in array) {
NSLog(#"Name :%#\n",[obj valueForKey:#"fname"]);
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#end
i am tried like this :-
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"ShowData"])
{
ShowViewController *destViewController = segue.destinationViewController;
destViewController.second = [[array valueForKey:#"fname"] componentsJoinedByString(angry)" , "];
NSLog(#" got data for array %#",destViewController.second);
}
}
ShowViewController.h:-
#import <UIKit/UIKit.h>
#import "SetViewController.h"
#interface ShowViewController : UITableViewController<UITableViewDelegate,UITableViewDataSource>
#property (nonatomic, strong) NSString *second;
#end
ShowViewController.m:-
import "ShowViewController.h"
#interface ShowViewController ()
{
NSMutableArray *acess;
}
#end
#implementation ShowViewController
#synthesize second;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
acess =[second componentsSeparatedByString:#", "];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [acess count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.text = [acess objectAtIndex:indexPath.row];
return cell;
}
ShowViewController is UITableView.When Click UItableView is open but data will be not Displayed So Please give me any idea
Follow following steps and also read programming guide of UITableview provided by apple:
After getting the array just reload your table view.
Make number of rows = array count.
Customize the cell as per your need.
If you only declared the array as per you shown in code then you must need to initialise it in view did load like this:
array=[NSMutablearray array];
after that get the values from db and stored in array an use UITable view delegate and datasource methods.
First declare your array in your viewDidload() method.
- (void)viewDidLoad
{
yourArray=[[NSArray alloc]initWithObjects:Obj1,obj2,obj3,obj4,obj5, nil];
}
and then use tableview delegate methods. to set array data to tableview.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [yourArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
// Configure the cell...
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
cell.textLabel.text=[yourArray objectAtIndex:indexPath.row];
return cell;
}
If you already have an NSArray that contains your strings, there is no need to go through the whole componentsJoinedByString/componentsSeparatedByString - you can just pass the array to your second view controller.
Accessing the passed data in viewDidLoad won't work though because when you set the property in prepareForSegue the view has already loaded.
Your prepareForSegue should be -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"ShowData"])
{
ShowViewController *destViewController = (ShowViewController *)segue.destinationViewController;
destViewController.fnames = [array valueForKey:#"fname"];
}
}
In your .h file for ShowViewController declare a property to receive frames -
#property (strong,nonatomic) NSArray *fnames;
Then your table data source methods will be -
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.fnames count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.text = [self.fnames objectAtIndex:indexPath.row];
return cell;
}
I have a TableView displaying a list of domain :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.tableView.dataSource = mainClass.domainList;
}
The domain list is set up like that :
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.domainList count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text = [[self.domainList objectAtIndex:indexPath.row] name];
return cell;
}
This works perfectly, it displays each domain in a row of my table view.
Now i would like to add a "Sub TableView" in each cell of my Table View to display a list of documents related to the domain.
I tried that :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableView *table = [[UITableView alloc] init];
table.dataSource = [self.domainList objectAtIndex:indexPath.row];
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text = [[self.domainList objectAtIndex:indexPath.row] name];
[cell.contentView addSubView table]
return cell;
}
It doesn't crash but it doesn't work neither. I mean the sublist doesn't appear anywhere.
What am i doing wrong?
datasource must be a class implementing the protocol UITableViewDataSource. It looks like you are setting it to a custom object. Create a separate class with the code you used to implement the first table, then set the sublist as source data. In the objc.io article “clean table view code” they explain how to make reusable datasources. Or you can just give it a try on your own.
Consider this code:
// ARRAYDATASOURCE.H
#import <Foundation/Foundation.h>
typedef void (^TableViewCellConfigureBlock)(id cell, id item);
#interface ArrayDataSource : NSObject <UITableViewDataSource>
-(id) init __attribute__((unavailable("disabled, try initWithItems:cellIdentifier:configureCellBlock")));
- (id) initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock;
- (id)itemAtIndexPath:(NSIndexPath *)indexPath;
#end
// ARRAYDATASOURCE.M
#import "ArrayDataSource.h"
#interface ArrayDataSource ()
#property (nonatomic, strong) NSArray *items;
#property (nonatomic, copy) NSString *cellIdentifier;
#property (nonatomic, copy) TableViewCellConfigureBlock configureCellBlock;
#end
#implementation ArrayDataSource
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock
{
self = [super init];
if (self) {
self.items = anItems;
self.cellIdentifier = aCellIdentifier;
self.configureCellBlock = [aConfigureCellBlock copy];
}
return self;
}
- (id)itemAtIndexPath:(NSIndexPath *)indexPath
{
return self.items[(NSUInteger) indexPath.row];
}
#pragma mark UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier
forIndexPath:indexPath];
id item = [self itemAtIndexPath:indexPath];
self.configureCellBlock(cell, item);
return cell;
}
#end
Please help i have been struggling passing back the data. I have 2 tableViews. 1st tableview=static table=RootVC. 2nd tableview=dynamic table=FirstVC. in RootVC i have a cell with two labels, "repeatLabel" and "repeatDetail" with a disclosure indicator. When i click on the cell it display the next table which is FirstVC, FistVC is populated with weekdays. after selection of my choice, i want the selected days to be passed back into RootVC in "repeatDetail" and when i go back still be able to see previously selected data.
My RootVC looks like this:
#import "RepeatViewController.h"
#interface SettingsViewController : UITableViewController
#property (strong, nonatomic) IBOutlet UILabel *repeatDetail;
#property (strong, nonatomic) IBOutlet UILabel *repeatLabel;
#property (strong,nonatomic) NSString *getRepeatDetail;
#property (nonatomic, strong) NSMutableArray *selectedDaysArray;
#end
in my RootVC.m
#import "SettingsViewController.h"
#interface SettingsViewController ()
#end
#implementation SettingsViewController
#synthesize repeatLabel,repeatDetail;
#synthesize getRepeatLabel;
#synthesize selectedDaysArray;
- (void)viewDidLoad
{
[super viewDidLoad];
repeatLabel.text = #"Repeat";
repeatDetail.text = getRepeatLabel;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
RepeatViewController *destinationController = segue.destinationViewController;
if( [destinationController isKindOfClass:[RepeatViewController class]] )
{
//You can reuse your selectedDays arrays
destinationController.selectedDays = self.selectedDaysArray;
[(RepeatViewController *)destinationController setCompletionBlock:^(NSArray *retDaysArray) // <- make this change
{
// Save your changes
self.selectedDaysArray = [NSMutableArray arrayWithArray: retDaysArray]; // <- make this change
NSLog(#"retDaysArray: %#", self.selectedDaysArray); //<- Add this debug line
}];
}
}
#end
My 1stVC.h
#import "SettingsViewController.h"
typedef void(^WeekdayCompletionBlock)(NSArray *retDaysArray);
#interface RepeatViewController : UITableViewController <UITableViewDataSource,UITableViewDelegate>
#property (nonatomic,strong) NSMutableArray *selectedDays;
#property (nonatomic, copy) NSArray *completionBlock;
#property (copy) WeekdayCompletionBlock returnBlock;
//#property (strong, nonatomic) IBOutlet UIBarButtonItem *saveButton;
-(IBAction)save:(id)sender;
#end
my 1stVC.m
#import "RepeatViewController.h"
#interface RepeatViewController ()
#end
#implementation RepeatViewController
#synthesize selectedDays= _selectedDays;
#synthesize completionBlock;
#synthesize returnBlock;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
completionBlock = [NSArray arrayWithObjects:#"Sunday", #"Monday", #"Tuesday", #"Wednesday", #"Thursday", #"Friday", #"Saturday", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 7;
}
- (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];
}
NSString *day = completionBlock[indexPath.row];
cell.textLabel.text = day;
if ([self.selectedDays containsObject:day])
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
//cell.textLabel.text = [completionBlock objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (!self.selectedDays)
self.selectedDays = [[NSMutableArray alloc] init];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
cell.accessoryType = UITableViewCellAccessoryNone;
//remove data from array
[self.selectedDays removeObject:[completionBlock objectAtIndex:indexPath.row]];
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//add data to array
[self.selectedDays addObject:[completionBlock objectAtIndex:indexPath.row]];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-(IBAction)save:(id)sender
{
NSUserDefaults *myNewWeekString = [NSUserDefaults standardUserDefaults];
[myNewWeekString setObject:self.selectedDays forKey:#"MY_KEY_FOR_ACCESING_DAYSOFWEEK"];
[myNewWeekString synchronize];
//NSLog(#"The selected day/s is %#",self.selectedDays);
if (self.returnBlock)
{
self.returnBlock(self.selectedDays);
}
[self.navigationController popViewControllerAnimated:YES];
// NSLog(#"The selected day/s is %#",self.selectedDays);
// if (self.returnBlock)
// {
// self.returnBlock([completionBlock objectAtIndex:indexPath.row]);
//}
}
/*
-(void) setReturnBlock:(WeekdayCompletionBlock)returnBlock
{
[self.selectedDays addObject:(self.returnArray);
}
- (NSArray *)setDats
{
return [NSArray arrayWithArray:[self.selectedDays copy]];
}*/
#end
When you work with static cells you have to bind the control you are using directly, there's no need.
So what I can suggest you is the following:
Bind your controls with some specific identifier, like labelFieldRow{rowid} example: labelFieldRow1.
So on prepare for segue, just check what's the selected row and pass the data you want to the destination controller.
Probably not the best, but it should work.
You have to pass data (selected by user before) from your RootVC to FirstVC. To do that in your RootVC add property to keep the selected data;
#property (nonatomic, strong) NSMutableArray *selectedDaysArray;
In prepareForSegue method you have to pass that array to let the table view know what needs to be selected:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *destinationController = segue.destinationViewController;
if( [destinationController isKindOfClass:[RepeatViewController class]] )
{
//You can reuse your selectedDays arrays
((RepeatViewController*)destinationController).selectedDays = self.selectedDaysArray;
[(RepeatViewController *)destinationController setReturnBlock:^(NSArray *retDaysArray) // <- make this change
{
// Save your changes
self.selectedDaysArray = [NSMutableArray arrayWithArray: retDaysArray]; // <- make this change
NSLog(#"DATA: %#", self.selectedDaysArray) //<- Add this debug line
}];
}
}
Remove this line from viewDidLoad you don't want to allocate it every time now you just pass it from rootVC
_selectedDays = [[NSMutableArray alloc] init];
And in cellForRowInIndexPath replace this line:
cell.textLabel.text = [completionBlock objectAtIndex:indexPath.row];
with this code:
NSString *day = completionBlock[indexPath.row];
cell.textLabel.text = day;
if ([self.selectedDays containsObject:day])
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
And change didSelectRowAtIndexPath: to
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (!self.selectedDays)
self.selectedDays = [[NSMutableArray alloc] init];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
cell.accessoryType = UITableViewCellAccessoryNone;
//remove data from array
[self.selectedDays removeObject:[completionBlock objectAtIndex:indexPath.row]];
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//add data to array
[self.selectedDays addObject:[completionBlock objectAtIndex:indexPath.row]];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Hope this help.