How Passing indexPath.row between views? - objective-c

I have table view, and I want to send the indexPath.row(index of selected row) to another view.
ProfesorViewController.m
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SCProfesoresCellTableViewCell *cell = (SCProfesoresCellTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
rowselected = indexPath.row;
}
ProfesorViewController.h
#interface ProfesorViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property long rowselected;
#end
I want to receive value of rowselected variable:
ProfesorDetailViewController.m
#synthesize rowselected;
- (void)viewDidLoad {
NSLog(#"BANDERA DE LA FILA %ld", rowselected);
}
ProfesorDetailViewController.h
#interface ProfesorDetailViewController : UIViewController
#property long rowselected;
#end
But the value of rowselected is always 0.
I don't know how to send the value of variable.

You have two classes with properties with the same name, but you never assign the value of one to the value of the other. At some point you need to take your instance of ProfesorDetailViewController and set rowselected on it, likely when initializing it.
ProfesorDetailViewController *detailViewController = [[ProfesorDetailViewController alloc] init];
detailViewController.rowselected = self.rowselected;

I can not understand where to pass data between ProfesorViewController and ProfesorDetailViewController so pass data between to view controller
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ProfesorDetailViewController *profesor=[[ProfesorDetailViewController alloc]initWithNibName:#"ProfesorDetailViewController" bundle:nil];
rowselected=indexPath.row;
search.Selected=_selected;
[self.navigationController pushViewController:profesor animated:YES];
}
Now you get the value of selected row index in ProfesorDetailViewController viewController properly..

Related

Push to viewcontroller and parse data

I have a simple UITableView which is suppose to push to a new Viewcontroller. When the Cell is pressed it should push to the new viewcontroller and send what number of row has been pushed. Is there a way to obtain this?
This is what i have at the moment, which dosent do anything.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
YoutubeViewController *youtubeViewController = [[YoutubeViewController alloc] initWithNibName:#"YoutubeViewController" bundle:nil];
[self.navigationController pushViewController:youtubeViewController animated:YES];
}
Do like this
This method is the delegate that will be called when a the user selects a cell in tableview
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//Write code here to push your viewcontroller
YourViewController *controller=[[YourViewController alloc]initWithNibName:#"YourViewController" bundle:[NSBundle mainBundle]];
controller.selectedRowValue = indexPath.row;
[self presentViewController:controller animated:YES completion:NULL];
}
In YourViewController.h
#interface YourViewController : UIViewController
#property int selectedRowValue;
#end
In YourViewController.m
#implementation YourViewController
#synthesize selectedRowValue;
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Selected Row %d",selectedRowValue);
}
Check protocol of UITableViewController delegate https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html.
Method You are looking for
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
yes do one thing
create property of integer type in your YoutubeViewController
like this
#property int selectedRowValue;
after that syntsize it in YoutubeViewController.m class
// YoutubeViewController.m
#implementation YoutubeViewController
#synthesize selectedRowValue
now you come class where ur table is and make some changes to it as shown bellow
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
YoutubeViewController *youtubeViewController = [[YoutubeViewController alloc] initWithNibName:#"YoutubeViewController" bundle:nil];
youtubeViewController.selectedRowValue=indexPath.row;
[self.navigationController pushViewController:youtubeViewController animated:YES];
}
now every thing done to check index value selected in youtube class NSLogout the value
//YoutubeViewController.m
- (void)viewDidLoad
{
// nslogout the value to check
NSLog(#"yours data selected from table%d",selectedRowValue);
}
now every thing done .
enjoy coding
Even you dont want this you can go by creating Constructor or by storing the value to NSUserDefaults

Datasource not returned by sub class of parent class implementing UITableView, throwing exception

I want to show some media of different categories (e.g. mostViewed, starred) in a UITableView. I created APPParentViewController which implements UITableViewDataSource and UITableViewDelegate protocol. In cellForRowAtIndexPath method in APPParentViewController, I return the appropriate cell which is filled with data coming from an array.
The array is actually instantiated in the init method in a sub class of APPParentViewController, which I exemplarily called APPChildViewController. There is one APPChildViewController for each media category. They just differ in the way the array is instantiated, the content of the array so to say.
I instantiate all APPChildViewController classes in another UIViewController ([[APPChildViewController alloc] init]) and then initially select one APPChildViewController to view (all happens in viewDidLoad method of that UIViewController). Working so far.
But when I want to show another APPChildViewController simply by removing the old view and adding the requested view (when the user requested it by pressing a button), I am getting the following exception:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:' ***
This is the code I am using (I removed everything which is not important in my opinion, so I hope it's still comprehensible):
APPParentViewController.h
#import <UIKit/UIKit.h>
#interface APPParentViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (strong, nonatomic) NSArray *media;
#property (strong, nonatomic) UITableView *tableView;
#end
APPParentViewController.m
#import "APPParentViewController.h"
#import "APPCell.h"
#interface APPParentViewController ()
#end
#implementation APPParentViewController
#synthesize media;
#synthesize tableView;
-(void)viewDidLoad
{
self.tableView = [[UITableView alloc] init];
[self.view addSubview:self.tableView];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.media count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellTableIdentifier = #"CellTableIdentifier";
static BOOL nibsRegistered = NO;
if (!nibsRegistered) {
UINib *nib = [UINib nibWithNibName:#"APPCell" bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier:CellTableIdentifier];
nibsRegistered = YES;
}
APPCell *cell = [self.tableView dequeueReusableCellWithIdentifier: CellTableIdentifier];
NSUInteger row = [indexPath row];
NSDictionary *rowData = [self.media objectAtIndex:row];
cell.title = [rowData objectForKey:#"Title"];
return cell;
}
#end
APPChildViewController.h
#import "APPParentViewController.h"
#interface APPChildViewController : APPParentViewController
#end
APPChildViewController.m
#import "APPChildViewController.h"
#import "APPCell.h"
#interface APPChildViewController ()
#end
#implementation APPChildViewController
- (id)init
{
self = [super init];
if (self) {
self.media = fill array...
}
return self;
}
It actually works when I copy the cellForRowAtIndexPath method implementation to all sub classes, but this is obviously not the way inheritance is intended to work...
When you make the switch, some cells will have a reference to the old child's media, and if that object is gone uh oh:
NSDictionary *rowData = [self.media objectAtIndex:row];
As soon so make the switch of dataSource, are you sending:
[self.tableView reloadData];
I'm assuming (hoping!) that you have just the one nib owned by the parent...

Master Detail Storyboard: Table View not showing cells (Objective-C)

I'm having troubles with the master viewController not showing any cells. This is the situation:
The app uses storyboard.
When the app launches, it goes to the navigationController
A button is pressed and connected to the table ViewController and it's set to "push" to it.
I've added the object and made a cell/detailView or whatever.
For some reason, the cell won't show up!!!
Here's the files:
MasterViewController.h:
#import <UIKit/UIKit.h>
#import "CraftingDetail.h"
#import "Crafting.h"
#class CraftingList;
#interface CraftingMaster : UITableViewController
#property (strong, nonatomic) CraftingDetail *detailViewController;
#property (strong, nonatomic) CraftingList *CL;
#end
MasterViewController.m:
#import "CraftingMaster.h"
#import "CraftingList.h"
#interface CraftingMaster ()
#end
#implementation CraftingMaster
#synthesize detailViewController = _detailViewController;
#synthesize CL;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
self.CL = [[CraftingList alloc] init];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return self.CL.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.CL.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
cell.textLabel.text = [self.CL craftingAtIndex:indexPath.row].Title;
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
DetailViewController.h:
#import <UIKit/UIKit.h>
#interface CraftingDetail : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *Image;
#property (strong, nonatomic) IBOutlet UITextView *Description;
#end
This is an old question, but having an unexpectedly empty table view is a common issue when starting to develop with table views so hopefully this answer will be of use to someone.
Here are some things to check when your table view is devoid of cells and you expected otherwise:
Are your data source object(s) (self.CL in this case) valid? (ie. Are they != nil and point to the correct object?)
Does numberOfSectionsInTableView: return an integer value greater than zero?
Does tableView:numberOfRowsInSection: return an integer value greater than zero?
Here are a couple of problems in MasterViewController.m above that need attention:
InitWithStyle: will not be executed when the view controller is instantiated in a storyboard. Instead, initWithCoder: should be used. I suspect this was the source of JomanJi's pain as this resulted in self.CL not being instantiated. (As an aside, the data source object/property: CL should be instantiated by assigning the value to the _CL ivar directly, not to the property. See "Initializing a property, dot notation" to learn why).
Due to returning (what is likely) the same value for numberOfSectionsInTableView: as tableView:numberOfRowsInSection: (ie. "return self.CL.count;"), the table view will display the same number of sections as there are cells in each section with each sections' cells containing the same data as the other sections. I doubt this effect was what the developer intended. (This is of course unless the count accessor method in CraftingList does something really strange).
Without seeing the code for CraftingList it is impossible to determine exactly what the problem is. However, given the age of the question, I suspect JomanJi has since figured it out on his/her own.

Can't reload Table View in tab bar controller

Hi I have a tab tab controller and my first tab includes a view with:
3 text fields
a submit button
a tableView
Once I fill in the text fields I click submit and it adds the information to my managedObjectContext which is an sqlite database (CoreData).
As soon as I click submit I want the tableView to reload to include the added object. Currently my tableView will display the data in the database but it will only add the new row when I stop and re-run the simulator
This is the code for when the add button is tapped, it is here that I can't get the reload tableView working because it says tableView is an undeclared identifier, what have i missed?
-(IBAction)addButtonTapped:(id)sender {
NSLog (#"Add Button Tapped");
NSLog(#"Adding %# units of item code %# at $%# each",quantityTextField.text,productTextField.text,priceTextField.text);
Products_MarketAppDelegate* delegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext* managedObjectContext = delegate.managedObjectContext;
NSManagedObject* newProduct;
newProduct = [NSEntityDescription insertNewObjectForEntityForName:#"Product" inManagedObjectContext:managedObjectContext];
[newProduct setValue:productTextField.text forKey:#"itemCode"];
[newProduct setValue:quantityTextField.text forKey:#"quantity"];
[newProduct setValue:priceTextField.text forKey:#"price"];
if ([managedObjectContext hasChanges])
NSLog(#"Managed Object Changed");
NSError* error;
[managedObjectContext save:&error];
// Insert Reload Table Code Here
// ** I have tried the following and it gives an error "Use of undeclared identifier 'tableView'"
//[tableView reloadData];
//[self.tableView reloadData];
}
As you can see below I have added the UITableViewDelegate & UITableViewDataSource in the header file. I have also hooked up the tableview in IB so that the delegate and datasource connections are linked to file's owner.
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#interface FirstViewController : UIViewController
<UIApplicationDelegate, UITableViewDataSource,UITableViewDelegate,NSFetchedResultsControllerDelegate>
{
IBOutlet UITextField *productTextField;
IBOutlet UITextField *quantityTextField;
IBOutlet UITextField *priceTextField;
NSMutableArray *items;
NSFetchedResultsController *fetchedResultsController;
}
#property (nonatomic, retain) NSMutableArray *items;
#property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
-(IBAction)addButtonTapped:(id)sender;
#end
This is the code to fill the tableView which works correctly
#pragma mark TableView
-(NSInteger)numberOfSectionsInTableView: (UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (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] autorelease];
}
// Configure the cell
Product* productItem =[fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%# x %# # $%#",productItem.quantity,productItem.itemCode,productItem.price];
return cell;
}
I have searched for answers on this site and on others but I must be doing something different and the solutions aren't helping me
Your UIViewController does not currently have an instance variable pointing to your tableview. Set one up:
#property (nonatomic, retain) IBOutlet UITableView *myTableView;
Remember to synthesize this in your .m
#synthesize myTableView;
Then in your code you can call
[self.myTableView reloadData];
You might have got confused by looking at code examples that use a UITableViewController instead of a UIViewController. The UITableViewController already has an instance variable called tableView, so your subclass wouldn't need it's own tableView instance variable declared. But you're using a UIViewController, so you must declare a tableView instance variable.
Thanks #MattyG for all your help. At first I wasn't sure if I was going against the norm and thats why it wasn't working.
I ended up solving the problem due to your suggestions & it works perfectly! I used the debugger and found that that although we had created a property for the table I had not created an IBOutlet and linked it in my nib file with:
IBOutlet UITableView *myTableView;
I guess this meant that I was telling myTableView to reload but it wasn't hooked up to my table and thus couldn't use the datasource methods.

Editable UITableView with a textfield on each cell

I am new to the iOS world and I want to know how to make a UITableView with custom cells that look and behave like the one you have when you try to configure some WiFi connexion on your device. (You know the UITableView with cells containing UITextFields with blue font where you set up the ip address and all that stuff... ).
To make a custom cell layout do involve a bit of coding, so I hope that dosen't frighten you.
First thing is creating a new UITableViewCell subclass. Let's call it InLineEditTableViewCell. Your interface InLineEditTableViewCell.h could look something like this:
#import <UIKit/UIKit.h>
#interface InLineEditTableViewCell : UITableViewCell
#property (nonatomic, retain) UILabel *titleLabel;
#property (nonatomic, retain) UITextField *propertyTextField;
#end
And your InLineEditTableViewCell.m could look like this:
#import "InLineEditTableViewCell.h"
#implementation InLineEditTableViewCell
#synthesize titleLabel=_titleLabel;
#synthesize propertyTextField=_propertyTextField;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Here you layout your self.titleLabel and self.propertyTextField as you want them, like they are in the WiFi settings.
}
return self;
}
- (void)dealloc
{
[_titleLabel release], _titleLabel = nil;
[_propertyTextField release], _propertyTextField = nil;
[super dealloc];
}
#end
Next thing is you set-up your UITableView as you normally would in your view controller. When doing this you have to implement the UITablesViewDataSource protocol method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. Before inserting your implementation for this, remember to #import "InLineEditTableViewCell" in your view controller. After doing this the implementation is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
InLineEditTableViewCell *cell = (InLineEditTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"your-static-cell-identifier"];
if (!cell) {
cell = [[[InLineEditTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"your-static-cell-identifier"] autorelease];
}
// Setup your custom cell as your wish
cell.titleLabel.text = #"Your title text";
}
That's it! You now have custom cells in your UITableView.
Good luck!