How to pass the properties of data to anotherViewController?(StoryBoard) - iphone

i want to pass the properties of data after select a tableviewcell.Please guide me.i already setup the detailviewcontroller.DataArray is my mutablearray in detailviewcontroller.peripheralManager is my NSbject.Peripheral is my device.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
peripheralManager=[[PeripheralManager alloc]init];
self.MeBle.enabled=NO;
device=[[NSMutableArray alloc]init];
}
- (void)peripheralManagerDidConnectPeripheral:(PeripheralManager *)peripheral
{
NSLog(#"%#",peripheral.deviceName);
[device addObject:[NSString stringWithFormat:#" %# ",peripheral.deviceName]];
// [device addObject:peripheral];
[self.deviceTable reloadData];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier=#"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if(cell==nil)
{
cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text=[device objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//DetailViewController *detail=[self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
// [self.navigationController pushViewController:detail animated:YES];
//[self performSegueWithIdentifier:#"TableDetails" sender:[device objectAtIndex:indexPath.row]];
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"TableDetails"]) {
DetailViewController *detail=segue.destinationViewController;
detail.dataArray=device;
}
}

in the prepareForSegue you should get the current selection index:
NSIndexPath *indexPath = [self.deviceTable indexPathForCell:sender];
now, you may either pass just this index to the destination controller OR specific object from you current array, its up to you.
detail.idx = [indexPath row];
Edit: there you don't need to implement
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
just in
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
change to this:
detailViewObject.objCurrentDevice=[device objectAtIndex:[[self.deviceTable indexPathForCell:sender] row]];

In interface builder, check out the seague runtime attributes section, u can create multiple cell same style but different identifier then cellForRowAtIndexPath return the cell by its row

Related

UITableView indexPathForSelectedRow return 0 (incorrect value)

I'm trying to make an upcoming events table in my app but when I select a row indexPathForSelectedRow always returns 0.
NSArray *upcommingTitle;
NSMutableArray *upcommingSubtitle;
NSMutableArray *upcommingTime;
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)datesTable numberOfRowsInSection:(NSInteger)section
{
return upcommingTitle.count;
}
-(UITableViewCell *)tableView:(UITableView *)datesTable cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
DatesCustomCell *Cell = [datesTable dequeueReusableCellWithIdentifier:cellIdentifier];
if(!Cell)
{
Cell = [[DatesCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
Cell.DatesTitle.text = [upcommingTitle objectAtIndex:indexPath.row];
Cell.DatesSubtitle.text = [upcommingSubtitle objectAtIndex:indexPath.row];
Cell.DatesTime.text = [upcommingTime objectAtIndex:indexPath.row];
return Cell;
}
self.datesTable.dataSource = self;
self.datesTable.delegate = self;
View Did Load
upcommingTitle = [[NSMutableArray alloc] initWithObjects:#"Title1", #"Title2", nil];
upcommingSubtitle = [[NSMutableArray alloc] initWithObjects:#"Sub1", #"Sub2", nil];
upcommingTime = [[NSMutableArray alloc] initWithObjects:#"Date1", #"Date2", nil];
But the following always returns 0 resulting in the "test" label to be "Title1"
View Did Appear
_test.text = [upcommingTitle objectAtIndex:self.datesTable.indexPathForSelectedRow.row];
Thanks for you help
try to push your another view in your didSelect method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Here, indexpath returns the selection of cell's indexpath, so put your code here
_test.text = [upcommingTitle objectAtIndex:indexPath.row];
//then push your view
}
UPDATED : then use this code
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier]isEqualToString:#"pushView"])
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
PushingViewController *pushView = [segue destinationViewController];
pushView._test.text = [upcommingTitle objectAtIndex:indexPath.row];
}
}
(void)tableView:(UITableView *)datesTable didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_test.text = [upcommingTitle objectAtIndex:indexPath.row];
}
Just put this code in your application.
Try not to deselect cell before presenting your seque
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//Call This Line
[self performSegueWithIdentifier:#"ShowMobileShopStore" sender:nil];
//Before This
[tableView deselectRowAtIndexPath:indexPath animated:true];
}
The initial question was: indexPathForSelectedRow return 0 (incorrect value),
Well, this is by-design, from the apple developer notes, the value returns an the IndexPath which can be NULL (is what you are seeing).
So, to do things right:
1) You need to test if the indexPathForSelectedRow is NOT NULL first
2) If it's not NULL then it would contain (.row) which would then give you the selected row-index, this starts from 0.
3) Please note that indexPathForSelectedRow.row would return ZERO in the case of indexPathForSelectedRow is NULL.
Here is the code that I've tested and works:
if (MyTableViewList.indexPathForSelectedRow)
{
long SelectedRow = MyTableViewList.indexPathForSelectedRow.row;
}
I hope this helps,

uitableview reloadRowsAtIndexPaths not working

I have a tableviewcell in the RegisterViewController, when i click on it, it push to the SelectCityViewController where i can pick a city from a uipickerview. and I have defined a delegate in the SelectCityViewController. But when i implement the delegate method, i got the city back from the pickerview and the selected indexpath from didSelectRowAtIndexPath in RegisterViewController. When i check the log, i get the city, and the selected indexpath. but when i call reloadRowsAtIndexPaths, the cell still got the old titlelabel text. the code:
SelectCityViewController.h
#protocol SelectCityDelegate <NSObject>
- (void)didGetCity:(City *)city;
#end
SelectCityViewController.m
- (void)finished:(UIBarButtonItem *)buttonItem
{
if ([self.delegate respondsToSelector:#selector(didGetCity:)]) {
[self.delegate didGetCity:self.city];
}
NSLog(#"%#", self.city.city);
[self.navigationController popViewControllerAnimated:YES];
}
RegisterViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 2) {
self.selectedIndexPath = indexPath;
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
SelectCityViewController *signUp = [storyBoard instantiateViewControllerWithIdentifier:#"SignVC"];
signUp.delegate = self;
[self.navigationController pushViewController:signUp animated:YES];
}
}
- (void)didGetCity:(City *)city
{
NSLog(#"%#", city.city);
NSLog(#"%#", selectedIndexPath);
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:selectedIndexPath];
cell.textLabel.text = city.city;
[self.tableView reloadRowsAtIndexPaths:#[selectedIndexPath] withRowAnimation:UITableViewRowAnimationFade];
}
I think the problem is in the below code you don't have to set the value here, because when you will reload, it will override the value with what is in the function where you are creating your cells.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:selectedIndexPath];
cell.textLabel.text = city.city;
Just reload the cell, and put above code in your
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Cell intialization and other things
cell.textLabel.text = city.city;
}
didGetCity needs to update the model that backs the table, not the table cell itself. How do you answer numberOfRowsInSection:? With the count of some array?
That array at index selectedIndexPath.row needs to change. cellForRowAtIndexPath: should initialize the cell with that same data. Then your didGetCity method updates the array and reloads. It should not refer to cells.

Accessing UITextField in UITableViewCell

I'm using a UITableView with a subclassed prototype cell with a UITextField. The cell is used 4 times total in 4 sections. This is the code for it:
...
- (void)viewDidLoad
{
[super viewDidLoad];
cellTitles = [[NSArray alloc] initWithObjects:#"Smell", #"Taste", #"Suits", #"Notes", nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [cellTitles count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [cellTitles count] / [cellTitles count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [cellTitles objectAtIndex:section];
}
- (AddInfoCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"AddInfoCell";
AddInfoCell *addInfoCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (addInfoCell == nil) {
addInfoCell = [[AddInfoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
addInfoCell.cellTextView.delegate = self;
return addInfoCell;
}
I want to add the text from each cell to the dataSource object:
-(IBAction)nextButtonPressed:(id)sender {
...
[[dataSource objectAtIndex:dataSourceIndex] setObject:* forKey:#"Smellnote"];
[[dataSource objectAtIndex:dataSourceIndex] setObject:** forKey:#"Tastenote"];
//etc
…
}
*text from cell 1
**text from cell 2
How can I access the text that I want?
Maybe you're looking at it wrong. Why not make the delegate for the textField be the cell itself, ie, in the Cell's class, set the delegate to File'sOwner or self in the init... method.
Create a reference to the dataSource and pass the dataSource to your cell, along with the #"Key" for your dictionary.
cell.dataSource = self.dictionary;
cell.dataKey = #"Tastenote";
//in cell .m
//textFieldDelegate method...
[self.dataSource setObject:self.cellTextView.text forKey:self.dataKey];

Change data source of tableView after selected row

I have table view with rows...after I selecting one item I want to show tableView with a new data source.
I tried to implement:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.searchDisplayController setActive:YES animated:YES];
Game *game = [self.filteredListContent objectAtIndex:indexPath.row];
//name your class names with capitals
NSMutableArray *arrayToBeAdded= [[NSMutableArray alloc]initWithArray:newgamearray];
[ListContent removeAllObjects];
[ListContent addObject:arrayToBeAdded];
but I getting exeption in the
[ListContent removeAllObjects];
Implementation of the init:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellID = #"cellSgames";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellID] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
Gmage *game = [self.ListContent objectAtIndex:indexPath.row];
In the .h file i declare:
NSArray AllList;
NSMutableArray ListContent;
any ideas?
Instead of manipulating the current list, create new UITableViewController with your desired data source. If you are using the UINavigationController it will create a better user experience and you will avoid your current problem.
Example:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
InnerTableViewController *innerTVC = [[InnerTableViewController alloc] initWithNibName:#"InnerTableViewController" bundle:nil];
[self.navigationController pushViewController:innerTVC animated:YES];
[innerTVC release];
}
Normally if you are resetting the array in didselect method and reloading your table view with new content it should work.
In your case i think at line:
[ListContent removeAllObjects];
ListContent is not a valid pointer. I don't see a reason to crash it here.

How to pass data back from detail view controller to uitableview?

In my app i making use of uitable to select category from my list.
my task is,when ever user click or select a cell he should be able to view the selected cell detail in next view(detail view). and when he select the item in a detail view he should be able to move back in a table view and should be able to see the selected item in a rootivew controller.
i am able to navigate properly from tableview to detail view,but i am not able to show the item which is selected in detail view to rootviewcontroller.
please help me out with this issue.
image one is my rootview controller page.
for example : if user select #"make" he will able to see all the releated category of #"make"
. in a next page(which image2).
image to is my detail page.
and when user select #"abarth" it should be display in a rootview controller page(which is page one).
following is my code of rootview controller page:
- (void)viewDidLoad
{
self.car = [[NSArray alloc]initWithObjects:#"Make",#"Model",#"Price Min",#"Price Max",#"State",nil];
[super viewDidLoad];
}
-(NSInteger) numberOfSectionInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.car count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *TextCellIdentifier = #"Cell";
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:TextCellIdentifier];
if (cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TextCellIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.textLabel.text = [self.car objectAtIndex:[indexPath row]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (0 == indexPath.row)
{
NSLog(#"0");
self.detailcontroller.title = #"Make";
}
else if (1 == indexPath.row)
{
NSLog(#"1");
self.detailcontroller.title = #"Model";
}
else if (2 == indexPath.row)
{
NSLog(#"2");
self.detailcontroller.title = #"Price Min";
}
else if (3 == indexPath.row)
{
self.detailcontroller.title = #"Price Max";
}
else if (4 == indexPath.row)
{
NSLog(#"3");
self.detailcontroller.title = #"State";
}
[self.navigationController
pushViewController:self.detailcontroller
animated:YES];
}
following is my detail view page code:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if ([self.title isEqualToString:#"Make"])
{
detail = [[NSArray alloc]initWithObjects:#"Any Make",#"Abarth",#"AC",#"ADAYER",#"Adelaide",#"ALFA ROMEO",#"ALLARD",#"ALPINE-RENAULT",#"ALVIS",#"ARMSTRONG",
#"ASTON MARTIN",#"AUDI",#"AUSTIN",#"AUSTIN HEALEY",#"Barossa",#"BEDFORD",
#"BENTLEY",#"BERTONE",#"BMW",#"BOLWELL",#"BRISTOL",#"BUICK",#"BULLET",
#"CADILLAC",#"CATERHAM",#"CHERY",#"CHEVROLET",#"CHRYSLER",#"CITROEN",
#"Country Central",#"CSV",#"CUSTOM",#"DAEWOO",#"DAIHATSU",#"DAIMLER",
#"DATSUN",#"DE TOMASO",#"DELOREAN",#"DODGE",#"ELFIN",#"ESSEX",
#"EUNOS",#"EXCALIBUR",#"FERRARI",nil];
if ([self.title isEqualToString:#"Abarth"])
{
detail = [[NSArray alloc]initWithObjects:#"HI", nil];
}
}
else if ([self.title isEqualToString:#"Model"])
{
detail = [[NSArray alloc]initWithObjects:#"Any Model", nil];
}
else if ([self.title isEqualToString:#"Price Min"])
{
detail = [[NSArray alloc]initWithObjects:#"Min",#"$2,500",
#"$5,000",
#"$7,500",
#"$10,000",
#"$15,000",
#"$20,000",
#"$25,000",
#"$30,000",
#"$35,000",
#"$40,000",
#"$45,000",
#"$50,000",
#"$60,000",
#"$70,000",
#"$80,000",
#"$90,000",
#"$100,000",
#"$500,000",
#"$1,000,000",nil];
}
else if ([self.title isEqualToString:#"Price Max"])
{
detail = [[NSArray alloc]initWithObjects:#"Max",
#"$2,500",
#"$5,000",
#"$7,500",
#"$10,000",
#"$15,000",
#"$20,000",
#"$25,000",
#"$30,000",
#"$35,000",
#"$40,000",
#"$45,000",
#"$50,000",
#"$60,000",
#"$70,000",
#"$80,000",
#"$90,000",
#"$100,000",
#"$500,000",
#"$1,000,000",nil];
}
else if ([self.title isEqualToString:#"State"])
{
detail = [[NSArray alloc]initWithObjects:#"Any State",
#"Australian Capital Territory",
#"New South Wales",
#"Northern Territory",
#"Queensland",
#"South Australia",
#"Tasmania",
#"Victoria",
#"Western Australia",nil];
}
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [detail 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 = [detail objectAtIndex:
[indexPath row]];
cell.font = [UIFont systemFontOfSize:14.0];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.navigationController popViewControllerAnimated:YES];
}
You need to make use of custom delegates. Create a protocol in your detailview and implement it in your rootview.Pass the selected string as parameter to delegate method and from the delegate method, display it in your textfield.
//something like this
#interface detailViewController
// protocol declaration
#protocol myDelegate
#optional
-(void)selectedValueIs:(NSString *)value;
// set it as the property
#property (nonatomic, assign) id<myDelegate> selectedValueDelegate;
// in your implementation class synthesize it and call the delegate method
#implementation detailViewController
#synthesize selectedValueDelegate
// in your didselectRowAtIndex method call this delegate method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self selectedValueDelegate])selectedValueIs:valueString] ;
[self.navigationController popViewControllerAnimated:YES];
}
#end
// In your rootViewController conform to this protocol and then set the delegate
detailViewCtrlObj.selectedValueDelegate=self;
//Implement the delegate Method
-(void)selectedValueIs:(NSString *)value{
{
// do whatever you want with the value string
}
Hi you will have to do it using protocols and delegate
Please see my linkon protocol and delegate
you can also do it by creating a variable in appdelegate , setting its property and accessing it in any other view .
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
delegate.yourVariable;