Objective C access variables from other classes? - iphone

I'm trying to get a variable from a class that I made from a table view. Basically what I want this to do is tell the other controller what row was selected so this is what I tried to do.
Table View Class .h file:
#property(nonatomic) NSInteger itemId;
-(NSInteger)itemId;
I would then make methods that set and get the variable in the .m file of the Table View Class
(I synthesized it and did all that stuff, I'm just showing you the methods)
-(NSInteger)itemId {
return self.itemId;
}
And now the table cell selected method...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)
indexPath {
NSUInteger row = [indexPath row];
self.itemId = row;
//segue stuff (if you want me to include this just let me know)
}
Thats all for that class and now the class that I need the value for
View Controller Class .h that is being pushed via segue
#property (nonatomic) NSInteger itemId;
View Controller Class .m
#import "TableViewController.h"
//Skip a few things
#synthesize itemId;
//skip a few things
-(void)viewDidLoad {
TableViewController *tvc = [[TableViewController alloc] init];
itemId = [tvc itemId];
NSLog(#"%i", itemId);
For some reason this doesn't work... When I print out the "itemId" in the "didselectrow" method it returns the right number but when I try to print it out in the other class it just gives me '0'
Any thoughts?
If there are things that I left out that you want to see in my code I'd be more than happy to write it out :) I just wanted to save time and space by cutting down the code a little.
Thanks in advance!
EDIT:
I did find a possible solution but it involves using the delegate. I'm sure there's got to be a better way of doing this so if you have any ideas, just let me know.

TableViewController *tvc = [[TableViewController alloc] init];
Doing this in a different class you create&initialize a new object, so it will be nill(for int 0). For sharing data between classes&view controllers use Delegates and properties.
With a little code i shall explain;
#import <UIKit/UIKit.h>
//YourClassNameAppDelegate.m
#interface YourClassName : UIResponder <UIApplicationDelegate>
{
NSString *uName;
NSDictionary *YourDictionary;
}
#property (copy, readwrite) NSString *uName;
#property (copy, readwrite) NSString *YourDictionary;
And in the other class you want to use this string and dictionary,
//import your delegate class
#import "YourClassNameAppDelegate"
.
.
.
//to me, do this in viewDidLoad(or something like that) method of new view controller
YourClassNameAppDelegate *sharedData= (YourClassNameAppDelegate *)([[UIApplication sharedApplication]delegate]);
.
.
-(IBAction)sharedData{
NSLog(#"Shared String: %#\n And Shared Dictionary: %#, sharedData.uName, sharedData.YourDictionary);
}

The - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *) is not invoked - you have to select a row to change the value of itemId, and that is not possible between the initialization of the table and the itemId = [tvc itemId]; line.

this code may helps you.
#import <UIKit/UIKit.h>
extern int outsider;
#interface ViewController : UIViewController {
}
#property int outsider;
#end
to all the .m files you #import the .h file where you declared the variable in can acces it.

You are creating a new instance of your table view controller within your detail view controller, this is incorrect and is not going to give you a reference to your original table.
Simply create a property on your pushed view controller which holds whatever detail information you want to pass. Then set this in prepareForSegue: in your table view controller, where segue.destinationViewController will give you a pointer to the VC that is about to appear.
Also, fix your accessor method as suggested by Yuji in comments.

I suggest saving the indexPath for the pressed row in a singleton. Here is a guide on how to use the singleton class to store objects and use them across classes.
In this example you can also just declare an instance variable in the singleton and set it when the row is pressed in the appropriate delegate method for your UITableView. This could be done like so:
#import <Foundation/Foundation.h>
#interface Singleton : NSObject {
NSIndexPath *tableViewPath;
}
#import "DataContainerSingleton.h"
#implementation DataContainerSingleton
#synthesize tableViewPath;
static DataContainerSingleton* _theDataContainerSingleton = nil;
+ (DataContainerSingleton*) theDataContainerSingleton;
{
if (!_theDataContainerSingleton)
_theDataContainerSingleton = [[DataContainerSingleton alloc] init];
return _theDataContainerSingleton;
}
- (id)init
{
self = [super init];
if (self) {
tableViewPath = [NSIndexPath indexPathForRow:0 inSection:0];
}
return self;
}
In your view controller with the UITableView just do like this:
#implementation
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
tableViewPath = indexPath;
}
You should adjust your initialization to what would be appropriate for your specific program!

Try this:
#property NSInteger itemId;
Hope this helps you

Related

How to pass/send the number of selected row in UITableViewController to another class?

Dudes, i'm having some trouble here in XCODE4.5 and I hope you can help me!
How can I pass or send the integer value of the selected row in UITableViewController to another ViewController, using the method didSelectRowAtIndexPath?
Here is my code :
SecondViewController.h
{
NSInteger myInteger;
}
#property(nonatomic) NSInteger myInteger;
SecondViewControl.m
-(void)viewDidLoad {
NSLog(#" the number is = %d",myInteger); //this is not working, I always get "the number is = 0 "
}
FirstViewController.h
#import "SecondViewController"
//...
FirstViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath) {
NSIndexPath *path = indexPath;
NSInteger theInteger = path.row;
NSLog(#"selected row = %d", theInteger); //code OK
//THE PROBLEM STARTS HERE!!!!!!!!!!!!!!!!!!
SecondViewController *second = [[SecondViewController alloc]init];
[second setMyInteger:theInteger];
// i'm trying to use "second.myInteger = theInteger;" , but it's also not working
}
}
Thank you guys!
Your myInteger iVar is unused b/c of how the compiler generates iVars and synthesizes getters/setters automatically for properties.
The compiler helps you when you declare properties so you don't need to declare your own iVars or use #synthesize unless you want behavior other than the default.
The line #property(nonatomic) NSInteger myInteger; causes the compiler to generate the equivalent of the following in your implementation.
#synthesize myInteger = _myInteger;
Therefore, the iVar being modified by the default setter is _myInteger.
You can do one of the following in SecondViewController. I prefer solution #1 b/c it is cleaner, less code and takes advantage of automatic compiler behavior.
In SecondViewController.h remove the myInteger iVar and in SecondViewController.m change any references to the iVar to either _myInteger or self.myInteger
or
In SecondViewController.m, explicitly synthesize the property to use your iVar by adding #synthesize myInteger;
EDIT: ADDED SPECIFIC EXAMPLE
// SecondViewController.h
#interface SecondViewContoller : UIViewController
#property(nonatomic) NSInteger myInteger;
#end
// SecondViewControl.m
-(void)viewDidLoad {
NSLog(#" the number is = %d", self.myInteger);
}
// FirstViewController.h
#import "SecondViewController"
//...
// FirstViewController.m
//
// rest of implementation
//
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath) {
NSIndexPath *path = indexPath;
NSInteger theInteger = path.row;
NSLog(#"selected row = %d", theInteger);
SecondViewController *second = [[SecondViewController alloc] init];
second.myInteger = theInteger;
// you need to present second somehow, viewDidLoad won't be called until then
// example if using a navigationController
[self.navigationController pushViewController:second animated:YES];
}
}
Passing parameters onto the next one should be done in the prepareForSegue:sender: method assuming you're using Storyboards in Xcode 4.5.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
SecondViewController *second = (SecondViewController *)segue.destinationViewController;
second.selectedIndex = selectedIndex;
}
}
Then in your didSelectRowAtIndexPath: method you can perform the segue:
[self performSegueWithIdentifier:#"YOUR_SEGUE_NAME_HERE"];
And it should pass the parameter to your second view again assuming you have a property in the header file of your SecondViewController like such:
#property (nonatomic, assign) int *selectedIndex;
EDIT:
In context with what you're trying to do you can easily make a private property in your FirstViewController at the top and store your selectedIndex from your didSelectRowAtIndexPath: there and pass it through in the prepareForSegue:
#interface FirstViewController() {
int selectedIndex;
}
And
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedIndex = indexPath.row
}
Hi i think you are missing to synthesize the myInteger Veriable modify your secondviewcontroller.m file
SecondViewControl.m
#synthesize myInteger;
-(void)viewDidLoad {
NSLog(#" the number is = %d",myInteger);
}
Hopefully this will help you :)

Objective-C: Problems accessing objects in other UIViewControllers

So I have a Custom UITableViewCell that holds a reference to its containing view controller (the VC that has its table in it).
// MyCell.h
#import <UIKit/UIKit.h>
#import "RootViewController.h"
#interface MyCell : UITableViewCell
#property (nonatomic, strong) IBOutlet RootViewController *rootViewController;
-(IBAction)checkBoxClicked:(UIButton*)sender;
// MyCell.m
#implementation MyCell
#synthesize rootViewController = _rootViewController;
-(IBAction)checkBoxClicked:(UIButton*)sender
{
[self setCheckBoxChecked:!_checkBoxChecked];
[_rootViewController refreshVisibleViewForCellTagged:self.tag];
}
In my cell I have a button that changes a variable and then calls a function in my rootViewController. The method is actually called however when I try to access any object in the RootViewController inside of the refreshVisibleViewForCellTagged method they are are '0x0' / nil;
// RootViewController.h
#interface RootViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) IBOutlet UITableView *myTableView;
// RootViewController.m
- (void) refreshVisibleViewForCellTagged:(NSInteger)cellTag
{
UITableView *tableView = self.myTableView; // nil
NSIndexPath *indexPath = [self.myTableView indexPathForSelectedRow]; // nil
MyCell *selectedCell = (MyCell*)[self.myTableView cellForRowAtIndexPath:indexPath]; // nil
if (selectedCell.tag == cellTag) {
NSLog(#"Refresh one way.");
} else {
NSLog(#"Do something else.");
}
}
Can anyone shed some light as to why I cant access any objects/variables in the RootController from within the method 'refreshVisibleViewForCellTagged'?
Please and thank you!
** My big question is Why can't I access any objects when calling a method in a view controller From a different view controller. There is some great programming truth that I am not aware of here, is it a permissions issue? Im not using #class (forward classing) in this instance.
As #trojanfoe said, delegation is a better way to do it.
Instead of #import "RootViewController.h", it is better to adop delegation. Because UITableViewCell is a child and RootViewController is the parent view. You don't want the child to talk directly with the parent.
To adopt delegation:
in MyCell.h file
remove #import "RootViewController.h".
revise MyCell.h as follows:
#protocol MyCellDelegate; // if you need to have forward declaration
#interface MyCell : UITableViewCell
// #property (nonatomic, strong) IBOutlet RootViewController *rootViewController;
#property (nonatomic) id <MyCellDelegate> delegate;
#end
#protocol MyCellDelegate <NSObject>
- (void)refreshVisibleViewForCellTagged:(NSInteger)cellTag;
#end
in MyCell.m.
#synthesize delegate;
-(IBAction)checkBoxClicked:(UIButton*)sender {
[self setCheckBoxChecked:!_checkBoxChecked];
//[_rootViewController refreshVisibleViewForCellTagged:self.tag];
[self.delegate refreshVisibleViewForCellTagged:self.tag];
}
in RootViewController.h adopt the delegation of MyCell
#import "MyCell.h"
#interface RootViewController : UIViewController <MyCellDelegate>
in RootViewController.m.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = // your implementation
//assuming all your cells are of MyCell kind
// set RootViewController as the delegate of each cell
((MyCell *)cell).delegate = self;
return cell;
}
implement the delegate method in RootViewController.m.
- (void)refreshVisibleViewForCellTagged:(NSInteger)cellTag {
// whatever you have
}
P.S. The above codes are for illustration. I didn't run them. If some part doesn't work, let me know, and I'll revise it.
The reason those objects in RootViewController are nil in the way you call, is because you are not accessing the same instance of RootViewController. It is a different (new) instance and hence all objects are nil.
Ignore the fact that view controllers are even involved. What you have are OBJECTS, connected together in a certain pattern. Accessing data in another view controller is no different from accessing data in any other object. There's no "magic" with view controllers, other than they have a few standardized connections to other objects.
IMHO, this is a poor design. For starters, your cell shouldn't need a reference to the view controller that the table it's in is in (read that twice, it barely makes sense just because the very idea of it is confusing). You have a strong reference to this view controller. So what happens when the OS tries to deallocate your view controller? It will never be able to, because the table view cell as a strong reference to it, keeping its retain count at 1. The same situation holds true for the cell. You risk running into a retain cycle here. Generally, child views should have weak references to their parents.
But this isn't even really a true parents/child relationship. I would suggest instead an approach like this, which all occurs in your view controller that contains the table view:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Assuming you set a reuse identifier "cellId" in the nib for your table view cell...
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:#"cellId"];
if (!cell) {
// If you didn't get a valid cell reference back, unload a cell from the nib
NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:#"MyCell" owner:nil options:nil];
for (id obj in nibArray) {
if ([obj isMemberOfClass:[MyCell class]]) {
// Assign cell to obj, and add a target action for the checkmark
cell = (MyCell *)obj;
[cell.checkMarkButton addTarget:self action:#selector(checkPressed:) forControlEvents:whateverEventYouWant];
break;
}
}
}
// Set the tag of the cell here, since we may get a different cell back from the reuse queue
cell.checkMarkButton.tag = indexPath.row;
return cell;
}
Now set up the method for the clicking of the checkmark button
- (void)checkPressed:(id)sender {
UIButton *checkmark = (UIButton *)sender;
// This will give you the row of the checked button
int checkedCellRow = checkmark.tag;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:checkedCellRow inSection:0];
// Now you can grab a reference to that cell if you need to
MyCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
}
This way, you keep all of the controller-related stuff in your controller class (i.e. how to handle the checkmark button being pressed), and you don't need to deal with this whackiness of referencing the view controller of your cell's table.
EDIT: I guess I should also help answer your questions...First of all, if you're saying that in your refreshVisibleViewForCell method, you're getting a nil value for self.myTableView, are you sure it is hooked up properly in IB? Even if it's hooked up, click the little x to unhook it and hook it up again to be sure. Also make sure you've #synthesized your myTableView property. Without seeing more code, an IB issue is my best guess as to why you're getting a nil value for tableView. A nil value here will result in a nil indexPath and selectedCell, also. As for your big question, you can access properties of objects within your view controller. Those properties can, of course, be objects. So in your example, if you have a tag property on selectedCell, you can access it from anywhere that you have a valid reference to selectedCell. If selectedCell is nil, the property will be nil. #class is better suited for header files. For instance, if you wanted to make your custom cell a property of your view controller, you might say:
#import <UIKit/UIKit.h>
#class MyCell;
#interface RootViewController : UIViewController
#property (nonatomic, strong) MyCell *cell;
#end
Then, in your implementation file, you would actually import MyCell.h. Giving the #class forward declaration just keeps you from having to import all of the details about the MyCell class in your header file. The header doesn't need to know about all of the properties and methods of MyCell, just that you intend on using it in the implementation file. So you #class in the header, #import in the implementation.
in RootViewController.h:
#interface RootViewController : UITableViewController <UITableViewDelegate>
in RootViewController.m:
- (void) refreshVisibleViewForCellTagged:(NSInteger)cellTag {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
MyCell *selectedCell = (MyCell*)[self.myTableView cellForRowAtIndexPath:indexPath]; // nil
etc...
I'm not seeing declarations of myTableView in your RootViewController. But if your RootViewController implements UITableViewController, you can use self.tableView to access the tableview. You don't need to keep a reference to it by yourself.
#RachelD, if your RootView is more complicated than just a UITableViewController consider using a separate class, such as RootTableViewController. Then in your RootView xib, create IBOutlet for RootTableViewController to reference it. Like this:
// RootTableViewController definition
#interface RootTableViewController : UITableViewController
{
}
// RootViewController definition
#interface RootViewController : UIViewController
{
RootTableViewController *table_c;
}
#property (nonatomic, retain) IBOutlet RootTableViewController *table_c;
Note that you need to drag an "Object" into the "Objects" section (for RootViewController) in the interface builder, and type RootTableViewController in the Custom Class section for this object. Right click this object, make sure its IBOutlet, view, 2 delegates are correctly set.
The reason why your myTableView is nil is because it's not properly initialized. I mean, if you don't use UITableViewController you are responsible for assigning it manually via interface builder or something.

Delegate not working properly

I am trying to pass some information between a subview and a parentview on the navigation stack using delegates.
However for some reason when the I execute the delegate from the subview then pop the subview from the navigational controller it never enters the delegate method that is set up in the parent view.. I have tried NSLogs & Breakpoints the thread is defiantly not making it to this delegate method in the main view so I was hoping you could help me out.
First Of all I will show you how I have set up my delegate, where I call it in my subview and then where I set it up in the mainview hopefully you guys will be able to see something I have not so far.
Subview.h // I have left out things not related to the delegate
#import <UIKit/UIKit.h>
//Delegate - Protocol stuff for passing data from this view to the parent view
#protocol PassSearchData <NSObject>
#required
- (void) setManufactureSearchFields:(NSArray *)arrayValues withIndexPath:(NSIndexPath *)myIndexPath;
#end
#interface SecondViewController : UITableViewController <UITableViewDataSource> {
//Delegate (Used to pass information back to parent view)
id <PassSearchData> delegate;
}
//Delegate (Used to pass information back to parent view)
#property (strong) id delegate;
#end
SecondView.m
#import "SecondViewController.h"
#import "FirstViewController.h"
#implementation SecondViewController
//..
//Delegate (Used to pass information back to parent view)
#synthesize delegate;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Access selected cells content (cell.textLabel.text)
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//Parent view logic (sends info back to the correct cell in parent view)
if (parentViewSelectedIndexPath.section == 0)
{
if (parentViewSelectedIndexPath.row == 0)
{
//Predicates restrict the values that will be returned from the query
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K like %#",#"MANUFACTURER",cell.textLabel.text];
filterArray = [parsedDataArrayOfDictionaries filteredArrayUsingPredicate:predicate];
[[self delegate]setManufactureSearchFields:filterArray withIndexPath:indexPath];
// NSLog(#"Filtered Array = %#", filterArray);
}
}
[self.navigationController popViewControllerAnimated:YES]; //pops current view from the navigatoin stack
}//...
Then this is how I set it up inside the FirstViewController
FirstViewController.h
#import <UIKit/UIKit.h>
#import "VehicleResultViewController.h" //With this included I can now use the PassSearchData delegates of this view for passing data
#interface VehicleSearchViewController : UITableViewController <PassSearchData> {
//..
FirstViewController.m
#import "VehicleSearchViewController.h"
#import "VehicleResultViewController.h" //Subview
//..
#pragma mark - Received data from Sub view delegates
//These are the delegate method for passing data from the child to the parent view (parent being this view, with the delegate being declared in the subview)
- (void) setManufactureSearchFields:(NSArray *)arrayValues withIndexPath:(NSIndexPath *)myIndexPath
{
manufactureSearchObjectString = [[arrayValues valueForKey:#"MANUFACTURER"] objectAtIndex:0];
manufactureIdString = [[arrayValues valueForKey:#"MANUFACTURERID"] objectAtIndex:0]; //Restricts Models dataset
manufactureResultIndexPath = myIndexPath;
}
If anyone knows what I'm missing/doing wrong any help would be really really heapful
any questions let me know.
Solution
In the firstviewcontroller when I go to load the secondviewcontroller inside
tableView:didSelectRowAtIndexPath: I forgot to set the secondviewcontrollers delegate before I pushed the view to the navigational stack.. so the missing code was this.
FirstView.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get the subview ready for use
VehicleResultViewController *vehicleResultViewController = [[VehicleResultViewController alloc] initWithNibName:#"VehicleResultViewController" bundle:nil];
//Pass the selected object to the new view controller.
[self.navigationController pushViewController:vehicleResultViewController animated:YES];
[vehicleResultViewController setDelegate:self];
//etc
thanks guys.
Ok, first, your delegate should be a weak reference to avoid retain cycles. But I suspect maybe the delegate isn't getting set. Can you show the code where SecondViewController is instantiated and the delegate is set? Can you set a breakpoint at the delegate call and verify that it is not nil?
I think you are not setting Delegate.
After Creation Instanace(object)of SecondViewController ,you have to set Delegate.
ie
SecondViewController *secondObj=[[SecondViewController alloc]initWithNibName:#"SecondViewController"> bundle:nil];
[secondObj setDelegate:self];

how to pass a string from one uiviewcontroller to another

I have tried a bunch of different things and feel like I am missing something really small..
I am trying to pass a string to another view controller but when i NSLog it i get a return of (null)...
heres what It looks like, I have tried so many examples I am almost ready to give up..
//secondview.h
#interface SearchResultsViewController : UITableViewController {
NSString *setRequestString;
}
#property (nonatomic, retain) IBOutlet NSString *setRequestString;
//secondview.m
//...
#synthesize setRequestString;
//...
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"%#", setRequestString);
}
//firstview.m
//...
#import "secondview.h"
//...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
//--- Idendify selected indexPath (section/row)
if (indexPath.section == 0) {
//--- Get the subview ready for use
secondview *sec = [[secondview alloc] initWithNibName:#"secondview" bundle:nil];
//...
switch (indexPath.row)
{
case 0: sec.title = #"Manufacture";
sec.setRequestString = [NSString stringWithString:#"yo"];
break;
//...
etc..
Declare a method in the class to which you want to send the data and call this method from the other class and pass the data as a parameter of the method. If u want keep it very simple u can try using NSUserDefaults. Hope this helps. Happy coding.... :)
Are you sure that "switch (indexPath.row) { case 0:" is getting called?
Try putting an NSLog in that case of your switch statement to make sure of that first.
First, you are using a pretty uncommon object name; "setRequestString" should better be named "requestString". Otherwise your synthesized setter will be called "setSetRequestString".
-- rest removed as that was bullshit, sorry, its late over here ;) ----

How to call a method of another Class?

EDIT2: I try to summarize my problem and the solutions:
I've got a TableViewController named DetailedViewController. My intention was to activate TouchesBegan to recognize actions like sliding etc, and normally, the method touchesbegan is replaced with the DidSelectRow method. In many posts on stackoverflow, subclassing the UITableView is the only possibility to realize this.
So i created a SpecificTable with .xib file and i used this as a subclass of UITableViewController by adding the SpecificTable as the nib-file.
Selecting a row works fine, and also the TouchesBegan method (i called a method IN the SpecificTable.m with an Alert.) But now i want to call a Method in the UITableViewController (DetailedViewController) where moveToNextItem is declared like
-(void)moveToNextItem:(id)sender
{
[self.navigationController
pushViewController:bbarChart animated:YES];
}
But by calling this method with [self moveToNextItem] the App crashes by touching. (in the Debugger-Mode, the App crashes in the line of [self moveToNextItem].
What is the right way to call the method of DetailedViewController.m?
Update: You should probably subclass UITableViewCell rather than UITableView. Then in your table view controller's cellForRowAtIndexPath: method, return an instance of this subclass rather than an instance of UITableViewCell.
You will also need to pass a DetailedViewController pointer on to the cell, so that you can invoke its moveToNextItem method in the touchesBegan, etc. methods.
Adapt this example to your needs:
MyTableViewCell.h
#class DetailedViewController;
#interface MyTableViewCell : UITableViewCell {
DetailedViewController *dvc;
}
#property (nonatomic, retain) DetailedViewController *dvc;
#end
MyTableViewCell.m
#import "MyTableViewCell.h"
#import "DetailedViewController.h"
#implementation MyTableViewCell
#synthesize dvc;
- (void)someMethod { // This would be your touchesBegan, etc. methods
[dvc moveToNextItem];
}
- (void)dealloc {
[dvc release]; // We retained dvc so we have to release it when we're done with it
[super dealloc];
}
#end
DetailedViewController.h
#interface DetailedViewController : UITableViewController {
// iVars here
}
// Methods and properties here
- (void)moveToNextItem;
#end
DetailedViewController.m
#import "DetailedViewController.h"
#import "MyTableViewCell.h"
#implementation DetailedViewController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyTableViewCell"];
if(cell == nil) {
cell = [[[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyTableViewCell"] autorelease];
cell.dvc = self; // This gives the cell a reference to the detailed view controller
}
return cell;
}
- (void)moveToNextItem {
// ...
}
#end
There are probably far better ways to achieve what you want, but this is the best I can do without more information.
Declare the method in DetailedViewController.h, and #import that file in SpecificTable.h.
if SpecificTable is really a subclass of DetailedViewController you can call
[self moveToNextItem];
as already mentioned.
but i think you mean a subview or not? so SpecificTable.view is a subview ob DetailedViewController.view
you have several options then. for example using NSNotificationCenter.
or what is probably also a good way for you is to setup an instance variable of DetailedViewController in your SpecificTable and assign it when you init your SpecificTable.
as an example:
// the parent view .m
testTVC *tableview = [[testTVC alloc] initsomething];
tableview.parentVC = self;
[self.view addSubView:tableview.view];
[tableview release];
now in your testTVC
// the .h
#interface testTVC : UITableViewController {
testVC *parentVC;
}
#property(nonatomic,retain) testVC *parentVC;
#end
// the .m
[parentVC moveToNextItem];
you also have to synthesize and release your parentVC.
Is [NSNotificationCenter defaultCenter] something you are looking for?