Passing and accessing object data outside table view - ios

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];
}

Related

How to pass data from Button click when the button is placed in UITableViewCell

I have a table view in which each row is having a button. Am storing the data as the button's title.
What I need : I want to pass the selected button's title to the destination view controller.
Code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *dict = _json[indexPath.row]
[cell.bRedeem setTitle:dict[#"n_id"] forState:UIControlStateNormal];
}
- (IBAction)redeemClicked:(UIButton *)sender {
UIButton *button = (UIButton *)sender;
_nID = button.currentTitle;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showOffers"]) {
offerList *details = (offerList *)segue.destinationViewController;
details.nearID = _nID;
}
}
You can add a Button target in your cellForRowAtIndexPath method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell.btnOne addTarget:self action:#selector(ButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnOne setTag:indexPath.row];
}
In the button action you can get the value of your Json Array using the [sender tag] value.
-(IBAction)ButtonClicked:(id)sender
{
NSDictionary *dict = [JsonArray objectAtIndex:[sender tag]];
NSLog(#"Selected Dictionary : %#",dict);
NSString * storyboardName = #"Main"; UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
NewViewController * NewView = [storyboard instantiateViewControllerWithIdentifier:#"NewViewControllerID"];
NewView.NearId = [dict valueForKey#"n_id"];
[self.navigationController pushViewController:NewView animated:YES];
}
Implement TableView cell delegates.

How to send data by clicking UITableViewCell's button to another ViewController

I want to send data using a button click which is in uitableviewcell. I got the data from web service. Each row button send different data to viewController.
Attach cellForRowAtIndex Method below:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
static NSString *identifier = #"CategoryCell";
NSDictionary *dictMenuData = [_arrHandMadeList objectAtIndex:indexPath.row];
CategoryCell *cell = (CategoryCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if(!cell) {
[tableView registerNib:[UINib nibWithNibName:#"CategoryCell" bundle:nil] forCellReuseIdentifier:identifier];
cell = (CategoryCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
}
cell.btnShowRatingDetails.tag = indexPath.row;
[cell.btnShowRatingDetails addTarget:self action:#selector(showRatingClicked:) forControlEvents:UIControlEventTouchUpInside];
[arrReview removeAllObjects];
//arrReview = [dictMenuData objectForKey:#"RivewData"];
[arrReview addObjectsFromArray:[dictMenuData objectForKey:#"RivewData"]];
[cell setupHandMadeCell:dictMenuData];
return cell;
}
Method for button is below:
-(void) showRatingClicked:(UIButton*)sender {
//if (sender.tag == currentIndex) {
ReviewVC *rvc = (ReviewVC*)[self.storyboard instantiateViewControllerWithIdentifier:#"ReviewVC"];
rvc.arrReviewDetails = arrReview;
rvc.strRestaurentName = [dictMenuData objectForKey:#"Restaurant_Name"];
rvc.strRestaurentId = [dictMenuData objectForKey:#"Restaurant_Id"];
rvc.strRestaurentRating = [dictMenuData objectForKey:#"Stars"];
[self.navigationController pushViewController:rvc animated:YES];
//}
}
Please help me
Thanks in advance
You need to get the index of selected cell button. You can get it from sender.tag.
-(void) showRatingClicked:(UIButton*)sender {
ReviewVC *rvc = (ReviewVC*)[self.storyboard instantiateViewControllerWithIdentifier:#"ReviewVC"];
NSDictionary *dictMenuData = [_arrHandMadeList objectAtIndex:sender.tag];
rvc.arrReviewDetails = [dictMenuData objectForKey:#"RivewData"]; //or as per your data
rvc.strRestaurentName = [dictMenuData objectForKey:#"Restaurant_Name"];
rvc.strRestaurentId = [dictMenuData objectForKey:#"Restaurant_Id"];
rvc.strRestaurentRating = [dictMenuData objectForKey:#"Stars"];
[self.navigationController pushViewController:rvc animated:YES];
}
Once cell.btnShowRatingDetails.tag = indexPath.row; button is assigned the tag you can get the data object in the action method, same way you get it using indexpath.row.
You need to use NSDictionary *dictReview = [_arrHandMadeList objectAtIndex:sender.tag]; in -(void) showRatingClicked:(UIButton*)sender to get the appropriate dictionary, then use it at the place of dictMenuData.
Remove dictMenuData altogether from your code.

Using an “IF” statement for popping to two possible View Controllers

Currently I just have a segue hooked up to a UITableView that pops to the next UITableView in the navigation stack.
What I need to do though now instead, is set up an if statement based on the text in the UITableView cell, to decide which of two possible UIViewControllers to pop to.
So ViewController2 needs to be able to pop either":
- back to ViewController1
OR
- forward to ViewController3
based on the text in the UITableView cell that is populated by JSON.
Can you help me out with that? Will post any code needed. Thanks!
Current ViewController:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Spring *spring = [springs objectAtIndex:indexPath.section];
Leaf *leaf = [spring.leafs objectAtIndex:indexPath.row];
cell.textLabel.text = leaf.shortName;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([segue.identifier isEqualToString:#"themes"]) {
UITableViewCell *cell = (UITableViewCell*)sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// Get reference to destination view controller
MRTViewController *tvc = (MRTViewController *)[segue destinationViewController];
}
}
UPDATE
Added code per #troops but still not sure how to pop to VC3
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *stringToCheck = #"AAA";
if([cell.textLabel.text isEqualToString:stringToCheck])
{
//Pop to VC1
[self.navigationController popToViewController:[[self.navigationController viewControllers]objectAtIndex:0] animated:YES];
} else {
//Pop to VC3, not sure what to put here
// Pass the info
tvc.spring = [springs objectAtIndex:indexPath.section];
tvc.leaf = [tvc.spring.leafs objectAtIndex:indexPath.row];
tvc.buttonNumber = _buttonNumber;
}
}
You could simply check the cell's textLabel's string: If you really want to use segues and not the tableView's delegate method of: didSelectRowAtIndexPath: That's why I based my answer off what your initial question/code looks like.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *stringToCheck = #"AAA";
if ([cell.textLabel.text isEqualToString:stringToCheck])
{
// Pop to VC1
[self.navigationController popToRootViewControllerAnimated:YES];
}
else
{
// Push to VC3
MRTViewController3 *tvc = [self.storyboard instantiateViewControllerWithIdentifier:#"YourID"];
tvc.spring = [springs objectAtIndex:indexPath.section];
tvc.leaf = [tvc.spring.leafs objectAtIndex:indexPath.row];
tvc.buttonNumber = _buttonNumber;
[self.navigationController pushViewController:tvc animated:YES];
}
}
Use delegate method, get cell, compare text.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if([cell.textLabel.text isEqualToString:#"Your String"])
{
//Pop or present view controller
}
}

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];
}

iOS carrying data over when pushing a new view

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);
}

Resources