iOS carrying data over when pushing a new view - ios

I have an app that is parses XML and stores in an NSObject ("Call"). I then display the table in a data like so:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Call *currentCall = [[xmlParser calls] objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = currentCall.call_name;
cell.detailTextLabel.text = currentCall.location;
cell.accessoryType = UIButtonTypeRoundedRect;
return cell;
}
My question is when I am pushing to the detail view controller, how do I set up the didSelectRowAtIndexPAth method to be able to access all the objects properties? I use to use this way, which works, but I am sure it is not the most efficient way. Thanks for the help.
Old way:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"indexPath = %d", indexPath.row);
Call *currentCall = [[xmlParser calls] objectAtIndex:indexPath.row / 2];
self.currentCallTypeDetail = currentCall.currentCallType;
self.unitsDetail = currentCall.units;
self.locationDetail = currentCall.location;
self.countyDetail = currentCall.county;
self.stationDetail = currentCall.station;
self.fullcallnumberDetail = currentCall.fullcallnumber;
self.latitude = currentCall.latitude;
self.longitude = currentCall.longitude;
self.callTypeDetail = currentCall.callType;
self.callNumberDetail = currentCall.callnumber;
self.timeDetail = currentCall.time;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
CallTypeDetailController *vc = [storyboard instantiateViewControllerWithIdentifier:#"calltypedetail"];
[vc setCurrentCallTypeDetail:self.currentCallTypeDetail];
[vc setUnitsDetail:self.unitsDetail];
[vc setLocationDetail:self.locationDetail];
[vc setCountyDetail:self.countyDetail];
[vc setStationDetail:self.stationDetail];
[vc setFullcallnumberDetail:self.fullcallnumberDetail];
[vc setCallTypeDetail:self.callTypeDetail];
[vc setCallNumberDetail:self.callNumberDetail];
[vc setTimeDetail:self.timeDetail];
[vc setLatitude:self.latitude];
[vc setLongitude:self.longitude];
[self.navigationController pushViewController:vc animated:YES];
NSLog(#"Selected Call = %#", self.currentCallTypeDetail);
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"indexPath = %d", indexPath.row);
Call *currentCall = [[xmlParser calls] objectAtIndex:indexPath.row / 2];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
CallTypeDetailController *vc = [storyboard instantiateViewControllerWithIdentifier:#"calltypedetail"];
[vc setCurrentCall:currentCall];
[self.navigationController pushViewController:vc animated:YES];
NSLog(#"Selected Call = %#", self.currentCallTypeDetail);
}

Related

Passing and accessing object data outside table view

I want to access object data that I used in my tableview method in my button action event, It is showing the error - "Use of undeclared identifier",
Here is my code snippets-
TableView method-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"BlogTableViewCell";
BlogTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
long index1 = 2 * (indexPath.row);
long index2 = index1 + 1;
if (index1 < [self.BlogsArray count]) {
cell.vw_blog1.tag = index1;
BlogModel *blog = [self.BlogsArray objectAtIndex:index1];
cell.lbl_blogTitle1.text = blog.blogTitle;
cell.lbl_blogDescripton1.text = blog.blogDesc;
}
My button Action method -
- (IBAction)btnAction_AuthorName1:(id)sender {
NSLog(#"Author1 of blog1 is clicked");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Consult" bundle:nil];
DRDetailsViewController *DRDetailVC = (DRDetailsViewController *)[storyboard instantiateViewControllerWithIdentifier:#"DRDetailsViewController"];
DRDetailVC.DoctorID = [NSString stringWithFormat:#"%#",blog.userId];
[APP_DELEGATE.navigationController pushViewController:DRDetailVC animated:YES];
}
It is showing error at blog.UserId .
Add Tag and create Button action in cellForRowAtIndexPath method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"BlogTableViewCell";
BlogTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.btn.tag = indexPath.row;
[cell.btn addTarget:self action:#selector(btnAction_AuthorName1:) forControlEvents:UIControlEventTouchUpInside];
}
You Button Action code.
- (IBAction)btnAction_AuthorName1:(UIButton *)sender {
BlogModel *blog = [self.BlogsArray objectAtIndex:sender.tag];
NSLog(#"Author1 of blog1 is clicked");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Consult" bundle:nil];
DRDetailsViewController *DRDetailVC = (DRDetailsViewController *)[storyboard instantiateViewControllerWithIdentifier:#"DRDetailsViewController"];
DRDetailVC.DoctorID = [NSString stringWithFormat:#"%#",blog.userId];
[APP_DELEGATE.navigationController pushViewController:DRDetailVC animated:YES];
}
Add Tag in cellForRowAtIndexPath method for your button.
cell.btn.tag = indexPath.row;
and then get the tag value for selected index
- (IBAction)btnAction_AuthorName1:(UIButton *)sender {
BlogModel *blog = [self.BlogsArray objectAtIndex:sender.tag];
NSLog(#"Author1 of blog1 is clicked");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Consult" bundle:nil];
DRDetailsViewController *DRDetailVC = (DRDetailsViewController *)[storyboard instantiateViewControllerWithIdentifier:#"DRDetailsViewController"];
DRDetailVC.DoctorID = [NSString stringWithFormat:#"%#",blog.userId];
[APP_DELEGATE.navigationController pushViewController:DRDetailVC animated:YES];
}

Passing data between viewcontroller through property

I have a dictionary on Viewcontroller A .I am passing it on viewcontroller B.On ViewController A it shows data on the dictionary of viewcontroller B.But ,In Viewcontroller it doesnt show any data in it?
ViewController A:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if (cell== nil) {
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
if(_List.count>0) {
[cell setupCell:[_List objectAtIndex:indexPath.row]];
ViewControllerB *vc=[[ViewController alloc]init];
vc.userIdInfo=[_List objectAtIndex:indexPath.row];
}
return cell;
}
ViewController B:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"_userIdInfo %#",userIdInfo);
if([userIdInfo valueForKey:#"UserID"]) {
[self fetchDataFromServer:getdetail];
}
}
This NSLog(#"_userIdInfo %#",userIdInfo) prints null. while vc.userIdInfo prints dictionary
{
Count = 3;
UserID = "6gdab241-j176-1121-lde2-as8d21f62231";
UserName = "abc#gmail.com";
}
In objective C, cellForRowAtIndexPath methods is used for showing the data.
As per code, you are intiallising the ViewController B in cellForRowAtIndexPath.
it will allocate ViewController B multiple time which lead to memory consumptions.
I would suggest you to initialise in ViewDidLoad of ViewController A.
For Passing the data from A to B, you need to Use didSelectRowAtIndexPath method of UITableViewDelegate.
Example:
ViewController A:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if (cell== nil) {
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
if(_List.count>0) {
//Use to show data
cell.textLabel.text = [NSString stringWithFormate:#"%#",[_List objectAtIndex:indexPath.row]]];
// [cell setupCell:[_List objectAtIndex:indexPath.row]];
// ViewControllerB *vc=[[ViewController alloc]init];
// vc.userIdInfo=[_List objectAtIndex:indexPath.row];
}
return cell;
}
ViweController B
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// 1st Type
ViewControllerB *vc=[[ViewController alloc]init];
vc.userIdInfo=[_List objectAtIndex:indexPath.row];
[self.navigartionController pushViewController:aVC animated:YES];
}
You need to do ViewController B initialization in DID select method like below.
Don't initialize it in cellForRowAtIndexPath.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// 1st Type
ViewControllerB *vc=[[ViewController alloc]init];
vc.userIdInfo=[_List objectAtIndex:indexPath.row];
[self.navigartionController pushViewController:aVC animated:YES];
//2nd Type
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewControllerB *aVC = [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
aVC.userInfo = <set your data>;
[self.navigartionController pushViewController:aVC animated:YES];
}
Hope this will helps.
The code
ViewControllerB *vc=[[ViewController alloc]init];
vc.userIdInfo=[_List objectAtIndex:indexPath.row];
only creates ViewController; it doesn't present it anywhere. moreover, the instance vc will be deallocated right after you leave the scope of
if(_List.count>0){}
your method
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"_userIdInfo %#",userIdInfo);
if([userIdInfo valueForKey:#"UserID"])
{
[self fetchDataFromServer:getdetail];
}
}
will never be called, because your view will never load.
I assume, that what you really want is to present your vc instance with navigationController instance, or from current viewController
[self.navigationController presentViewController: vc animated: YES completion: nil];

Detail View Controller from Table View Controller WITHOUT Storyboard?

I have a tableview in a controller that shows receipts and their image, date created, etc.
I made it so when the user taps a cell, it goes to DetailViewController. Using this code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ReceiptDetailViewController *controller = [[ReceiptDetailViewController alloc] initWithNibName:#"ReceiptDetailViewController" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
}
I'd like to pass the image, date, category, etc, to my new view in a UIImageView, textView, etc.
This is the code for my Table in the first controller:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
Receipt *receipt = [self.receiptsArray objectAtIndex:indexPath.row];
ReceiptCategory *category = receipt.relationshipToCategory;
ReceiptImage *image = receipt.relationshipToImage;
cell.textLabel.text = category.receiptCategory;
cell.detailTextLabel.text = receipt.date.description;
if(self.imageCache.count <= indexPath.row) {
[self.imageCache addObject:[UIImage imageWithData:image.data]];
}
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
imageView.image = [self.imageCache objectAtIndex:indexPath.row];
cell.imageView.image = imageView.image;
return cell;
}
How do I pass this data? I have searched around for two days now and all solutions include a storyboard, which I am not using.
You should get reference to your receipt in didSelectRowAtIndexPath: and pass it to ReceiptDetailViewController. I assume you have property to accept the data in ReceiptDetailViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get reference to receipt
Receipt *receipt = [self.receiptsArray objectAtIndex:indexPath.row];
ReceiptDetailViewController *controller = [[ReceiptDetailViewController alloc] initWithNibName:#"ReceiptDetailViewController" bundle:nil];
// Pass data to controller
controller.receipt = receipt;
[self.navigationController pushViewController:controller animated:YES];
}
It this example you should create property in ReceiptDetailViewController.h file:
#property(nonatomic, strong) Receipt *receipt;
Now you can use it in your ReceiptDetailViewController object.
You should just use Table View Delegate Method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
There you can retrieve the selected receipt and pass the data to the detail view like that:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ReceiptDetailViewController *controller = [[ReceiptDetailViewController alloc] initWithNibName:#"ReceiptDetailViewController" bundle:nil];
Receipt *selectedReceipt = [self.receiptsArray objectAtIndex:indexPath.row];
controller.receipt = selectedReceipt;
[self.navigationController pushViewController:controller animated:YES];
}
You can create a custom class for your detailed view controller and create an object of the same when the user clicks on any cell.
Something like this
DetailViewControllerClass *newObject = [[DetailViewControllerClass alloc] init];
newObject.data1 = dataToBeSent ; //assign data
You should make an object of Receipt in ReceiptDetailViewController and make the property nonatomic and strong Than in tour view controller Write this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Receipt *receipt = [self.receiptsArray objectAtIndex:indexPath.row];
ReceiptDetailViewController *controller = [[ReceiptDetailViewController alloc] initWithNibName:#"ReceiptDetailViewController" bundle:nil];
controller.objReceipt= receipt;
[self.navigationController pushViewController:controller animated:YES];
}

Pass data to new view from tableView

I have a table view which pushes a detailed view on cell click. The new view pushes however I'm trying to pass a web address to the detailed view which loads a webView but I'm unsure on how to do this. Here is my code:
-(void)setupArray {
webAddress = [[NSMutableDictionary alloc]init];
[webAdress setObject:#"http://www.google.com.au" forKey:#"first item"];
[webAdress setObject:#"http://www.yahoo.com.au" forKey:#"second item"];
menuItems = [webAdress allKeys];
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [webAdress count];
}
-(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 = [menuItems objectAtIndex:indexPath.row];
return cell;
}
- (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *detailView = [self.storyboard instantiateViewControllerWithIdentifier:#"detail"];
[self.navigationController pushViewController:detailView animated:YES];
}
Any help would be greatly appreciated.
You need to use a property for that in your detail view and pass the URL in the didSelectRowAtIndexPath method like this :
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detailView = [self.storyboard instantiateViewControllerWithIdentifier:#"detail"];
detailView.webAddress = [menuItems objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailView animated:YES];
}
and in your DetailView :
#property (nonatomic, strong) NSString *webAddress;
You should add an instance variable to the DetailViewController which will hold the address & set it to the desired value. Then (with the proper accessor) set it before/after pushing the view.
e.g. if you defined the variable as webAddress:
DetailViewController *detailView = [self.storyboard instantiateViewControllerWithIdentifier:#"detail"];
[detailView setWebAddress:[webAddress objectForKey:[menuItems objectAtIndex:[indexPath row]]]]; // or some other way to get the correct address
[self.navigationController pushViewController:detailView animated:YES];
The only thing that remains to be done is to set the web view's address to this value on viewWillAppear: or something.
Edit:
A sample viewWillAppear: method would look like this:
- (void)viewWillAppear:(BOOL)animated
{
// construct request
NSURL *url = [NSURL URLWithString:webAddress];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[webView loadRequest:req];
[super viewWillAppear:animated];
}

Iphone tableview

I am using below code for getting index number of the row. I want to get the Text of row. Please tell me, what modifications are required to get the text from each row.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *__strong)indexPath{
DetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"Detail"];
[self.navigationController pushViewController:detail animated:YES];
detail.rowNum.text = [NSString stringWithFormat:#"Row: %d", (indexPath.row) ];
}
thanx in advance :)
You can get cell with all its properties this way:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *__strong)indexPath{
DetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"Detail"];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
detail.rowNum.text = [NSString stringWithFormat:#"Row: %d", (indexPath.row) ];
detail.someLabel.text = cell.textLabel.text;
[self.navigationController pushViewController:detail animated:YES];
}
Is this what you want? Text from selected cell?
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *__strong)indexPath{
DetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"Detail"];
[self.navigationController pushViewController:detail animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
detail.rowNum.text = cellText;
}
Update ur code as above.

Resources