Pass data to new view from tableView - ios

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

Related

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

Uitableview cell transition

My tableViewcell is in array and i want to select diary cell from which i need to navigate to next screen.i dont know what to implement in did select row method.please help me out
table=[[UITableView alloc]init];
table.frame=CGRectMake(0, 0, 250, CGRectGetHeight(self.view.frame));
table.delegate=self;
table.dataSource=self;
table.backgroundColor=RGBCOLOR(255,255,255);
tabledata=[NSMutableArray arrayWithObjects:#"Me and My stuff",#"Upgrade Membership",#"Diary",#"Progress",#"Friends",#"My awards and points",#"Messages",#"Blogs",#"Fun stuff",#"Remainders",#"Settings",#"Signout",nil];
table.backgroundColor=RGBCOLOR(255,239,213);
table.sectionFooterHeight=44;
table.sectionHeaderHeight=44;
table.separatorStyle=UITableViewCellSeparatorStyleNone;
[self.view addSubview:table];
self.view.backgroundColor=RGBCOLOR(255,239,213);
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellidentifier =#"table";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellidentifier];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier];
cell.opaque=NO;
cell.backgroundColor=RGBCOLOR(255,239,213);
cell.textLabel.textColor=RGBCOLOR(32,178,170);
cell.selectionStyle=UITableViewCellSelectionStyleBlue;
}
cell.textLabel.text=[tabledata objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
assume that the tableview contains in our first view controller
1. SecondViewController.h
#property(nonatomic, strong) NSString *fullName;
2. SecondViewController.m
#synthisize fullName;
- (void)viewDidLoad
{
NSLog(#"name ==%#",fullName);
[super viewDidLoad];
}
3. FirstViewController.m
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row==2) // this is diary cell
{
SecondViewController *temp = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
temp.fullName=[tabledata objectAtIndex:indexPath.row];
[self.navigationController pushViewController:temp animated:YES];
}
else
{
// do nothing
}
}

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

My table view is loading the detail view in a dark screen

So i have a table view hooked up to a plist with urls. When I click on the table view cells i want it to take me to the detail view, but the only problem right now is when i click on the cell to take me to the detail view it just loads a dark screen with nothing on it. I don't receive any errors on the compiler so i have no idea what is wrong. I have reset the stimulator and tried restarting my computer but now I'm starting to think there is something wrong with the code. Can someone help?
TableViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSString *myListPath = [[NSBundle mainBundle] pathForResource:#"myList" ofType:#"plist"];
tableData = [[NSArray alloc]initWithContentsOfFile:myListPath];
NSLog(#"%#",tableData); }
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [tableData count]; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if( cell == nil )
{
NSLog(#"Cell Creation");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
//Set Data For each Cell
cell.textLabel.text = [[tableData objectAtIndex:indexPath.row]objectForKey:#"cellName"];
cell.detailTextLabel.text = [[tableData objectAtIndex:indexPath.row]objectForKey:#"cellSubtitle"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Index Selected,%d",indexPath.row);
WebViewController *View = [[WebViewController alloc] init];
NSString *urltoPass = [NSString stringWithString:[[tableData objectAtIndex:indexPath.row]objectForKey:#"cellSubtitle"]];
View.urlString = [[NSString alloc] initWithFormat:#"http://%#",urltoPass];
View.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:View animated:YES completion:nil];
}
When you make a controller in a storyboard, you need to get an instance of that view controller by using instantiateViewControllerWithIdentifier:, not by using alloc init.
WebViewController *View = [self.storyboard instantiateViewControllerWithIdentifier:#"WebView"];
In the storyboard, you need to give the controller the identifier "WebView".

Tableview with details

I have created a tableview with the data from an array. Now i want the details for all the rows of the tableview. If i select any recipe from the tableview it should show me all the ingredients and procedure to prepare that recipe with a pic of that particular recipe on top. I am new to this field so kindly help.
Here's "ViewController.m"
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
RecipeList = [[NSMutableArray alloc]init];
[RecipeList addObject:#"Chicken Kabab"];
[RecipeList addObject:#"Chicken Tikka"];
[RecipeList addObject:#"Chicken 65"];
[RecipeList addObject:#"Chicken Do Pyaza"];
CGRect frame = self.view.frame;
RecipeTable = [[UITableView alloc]initWithFrame:frame style:UITableViewStylePlain];
RecipeTable.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
RecipeTable.backgroundColor = [UIColor cyanColor];
RecipeTable.delegate = self;
RecipeTable.dataSource = self;
[self.view addSubview:RecipeTable];
[RecipeTable setScrollEnabled:YES];
[RecipeTable setUserInteractionEnabled:YES];
[RecipeTable setRowHeight:35];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"RECIPES";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return RecipeList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
cell.textLabel.text = [RecipeList objectAtIndex:indexPath.row];
return cell;
}
#end
Just pass recipe name to the detailViewController. Then depending on the name of the recipe you can load the suitable image in UIImageView.
In the code recipename is an NSString in detailViewController. Declare it as a property..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
NSString *name=[recipe objectAtIndex:indexPath.row];
detailViewController.recipename=name;
[self.navigationController pushViewController:detailViewController animated:YES];
}
Then in the detaiViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
if([recipename isEqualToString:#"Pizza"])
{
UIImage *image = [UIImage imageNamed: #"pizza.png"];
[img setImage:image];
}
else if([recipename isEqualToString:#"Chicken 65"])
{
UIImage *image = [UIImage imageNamed: #"chicken.png"];
[img setImage:image];
}
}
you must use the DidSelectRow Delegate of UITableView . Then if you select a recipe it calls the DidSelectRow delegate .Inside this delegate you do the coding for pushing to a new ViewController . Create an UIImageView on top of your new ViewController , then pass the image from your TableViewCell to the UIImageView of your new viewController
If you want the details of a particular Dish populated in another ViewController that is pushed, the easiest way is by creating an NSObject with all the details required for that particular dish and maintaining it as an array. When you select a row in tableView, the didSelectRowAtIndexPath: get the object at that indexPath and pass it to the next VC which is being pushed. In the detail VC you can populate the details with that from the object.
Instead of doing like this
RecipeList = [[NSMutableArray alloc]init];
[RecipeList addObject:#"Chicken Kabab"];
do something like
RecipeList = [[NSMutableArray alloc]init];
[RecipeList addObject:dishObj];
where dishObj is an NSObject, of Class Dish which contains Dish name, image and recipe.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
Dish *dishObject = [RecipeList objectAtIndex:indexPath.row];
cell.textLabel.text = dishObject.dishName;
return cell;
Try this ,
you must use the DidSelectRow Delegate of UITableView
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
NSString *strDishName = [RecipeList objectAtIndex:indexPath.row];
detailViewController.strDishDetail =strDishName;
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
}
I hope the following tutorial will useful for u..Segue

Resources