PDA

View Full Version : Calling button method from another class




Abrexas
Feb 6, 2012, 09:23 PM
Hey guys, so this is pretty much the last thing that I need to solve before being done with my app, and it's pretty easy that I am sure this is a very simple problem that I am just overlooking the answer for no reason. Here it is.

Most of my app is written in one class (I know it's bad practice but that's just what happened.)
There is a UITableView in that class, that is filled with custom cells from another class.

The problem that I have is that I have a button inside of the custom cells, and I need that button to work with the other class. Now had I been working with java or C I would probably either use inheritance or make the method static, but I don't know how to do this in Obj C.

Here is the goal: I need to either implement the bottom method
-(IBAction)button:(id)sender;
in the other class, or I just need to be able to access a text field from the first class, inside of the custom cells button method. (i.e. When I click the button in the cell, I need something to print inside of a text field that is in the first class. There are also some other variables that I need to access, but I can do those once I get this problem solved)

I don't see the need for me to write down my code, since this is a very general question and isn't exactly code specific, but if you need it then I could show some of it.

Thank you for all the help in advance!!
- Steven French



dejo
Feb 6, 2012, 11:37 PM
Well, your tableViewController instantiates your custom tableViewCells, correct? So, as long as your IBAction method is public, you should be able to call it.

Abrexas
Feb 7, 2012, 03:49 AM
How do I know if the method is public? Could you show me the syntax for calling this? If I just call it as -(IBAction)button:(id)sender{ } then nothing happens

jnoxx
Feb 7, 2012, 05:02 AM
Sorry, but this is some basic Objective-C, and just OOP in general (in a small way).
Your method is public if it's publicly avaible in your header file, not if it's in a private interface.. if you import it in another class, have a pointer to it, or whatever, you can call it's method..

dejo
Feb 7, 2012, 09:35 AM
As jnoxx said, this is basic Objective-C. I suggest you step away from the real coding and go (re)learn the fundamentals of Objective-C programming.

Abrexas
Feb 9, 2012, 09:31 PM
Yes I understand that this is a basic problem. I know how to do this in Java easily and I understand the logic behind it. I just don't know the syntax to do this in Objective-C and I am having trouble figuring it out on my own.

I have a book on Objective-C and have searched through many documents and forums.

I would really appreciate some help, and by help... not just someone telling me it is an easy solution...

Maybe an example of the syntax, or a link (or even suggestion) to something that might help. I didn't give you my code because I don't want you to write it for me, I did ask the question because I felt you might be willing to help me out.

Thanks for responding regardless.
- Steven French


Edit:
I have tried importing the .h files and making a pointer. I am pretty sure I got the pointer syntax wrong, but importing the header didn't allow me to access the method.

dejo
Feb 10, 2012, 12:53 AM
I have a book on Objective-C...

What book? Please be specific.

What does this book tell you about declaring public methods for a class?

jnoxx
Feb 10, 2012, 02:30 AM
Yes I understand that this is a basic problem. I know how to do this in Java easily and I understand the logic behind it. I just don't know the syntax to do this in Objective-C and I am having trouble figuring it out on my own.

I have a book on Objective-C and have searched through many documents and forums.

I would really appreciate some help, and by help... not just someone telling me it is an easy solution...

Maybe an example of the syntax, or a link (or even suggestion) to something that might help. I didn't give you my code because I don't want you to write it for me, I did ask the question because I felt you might be willing to help me out.

Thanks for responding regardless.
- Steven French


Edit:
I have tried importing the .h files and making a pointer. I am pretty sure I got the pointer syntax wrong, but importing the header didn't allow me to access the method.

I literally told you what to do.. There is nothing more to say about it.
And if you are messing Pointer Syntax up wrong, what are you doing trying to program an app, maybe make some examples in the book, how to make pointers, which is the BASE of Objective-C. Unless your compiling C/C++ Which I think you aren't.
None the less, you're missing too much fundementals, and I really recommand taking a few days (that's not alot in a lifetime), to just go read the fundementals again.

Abrexas
Feb 10, 2012, 12:49 PM
I apologize for my tone before, I am just getting really frustrated on such a simple problem.

The book I have is "Programming in Objective-C" By Stephen G. Kochan (Third Edition)

If it helps at all, I am ready to write an app like this, especially since I am almost done with it. Here is a link to a demo of what the app is. Although, I have done a LOT with it since and it is pretty much done. The app most likely won't make since to you because it is targeted at a sport that I do and the video is made to explain the app to other people in the sport, but it might show you enough that I do know what I'm doing.
http://www.youtube.com/watch?v=eFEivA-nRls&list=UUxhiFZ0TJqOC_uyBAVakiPw&index=1&feature=plcp

I am confident that a big problem I am having is that I am taking both Java and C classes this semester, and everything I have learned about Objective-C has been done on my own (Through books and tutorials). I understand pointers, inheritance and private methods and all that. I just don't know how to do it in Objective-C and I am getting frustrated hahha


I tried creating an instance of the second class inside the first (after importing the .h) and I did it like this.

ButtonClass *object = [[ButtonClass alloc] init];
[object desiredMethod];

Although as you can see that does nothing for calling the method on button press.

Could I at least get a specific topic to look up? Or a link to a page? My app is soooooo close to done, and I just want to finish it haha. Then I promise I will go back to the learning boat before my next project ^^

jonnymo5
Feb 10, 2012, 01:34 PM
Do you know how to handle button press at all? Could you print out a log message when you push a button?

If you can, then just replace your NSLog statement with the call to the method like you have above.

Abrexas
Feb 10, 2012, 01:58 PM
Do you know how to handle button press at all? Could you print out a log message when you push a button?

If you can, then just replace your NSLog statement with the call to the method like you have above.

Yes I can handle button press. If you watch my youtube link you will see that. Right now when I press the button (In the custom cell) I have an NSLog print "button test" and it works fine. However, when I try to use the method as previously shown (calling from the other class) the NSLog doesn't appear. Likewise, if I try it in the other direction (as in trying to access a TextField from the main class in the class with the button) I get the same effect... nothing =/

jonnymo5
Feb 10, 2012, 02:03 PM
I don't have youTube access here. Why don't you share the code for the method you call when you press the button.

Abrexas
Feb 10, 2012, 02:25 PM
Why don't you share the code for the method you call when you press the button.

*BasicComboGenViewController is the main class.
*editAddCombo is the TextField inside of the main class
*This method is called inside of my custom cells class.

-(IBAction)editButton:(id)sender{
BasicComboGenViewController *object = [[BasicComboGenViewController alloc]init];
object.editAddCombo.text = @"Well Hai!";
NSLog(@"Button Test");

}

As you can see, for this I am not trying to call the method in the main class, but rather trying to access the main classes fields inside of the custom cells classes button method.

The result of this is a successful NSLog, but the TextField remains unchanged. I have a button method inside of my main class that successfully alters the very same TextField so I know that the problem isn't in the connections or anything

dejo
Feb 10, 2012, 02:32 PM
I don't have the Third Edition of Kochan's book (just the second) but in the page about "The @interface Section" in the "Classes, Objects, and Methods" chapter, where he talks about methodDeclarations, those are public methods. That is, any method declared in the @interface is a public method.

Anyways, I thought you were wanting to access a method from your custom UITableViewCell from within your UITableViewController. Is that no longer the case? If it still is the case, then please include the code (methods and all) where you instantiate your custom cells as well as the .h (@interface) for your UITableViewCell subclass.

Abrexas
Feb 10, 2012, 02:48 PM
Oh sorry, in my first post I said how I don't think it matters in what direction I do this, either calling the button method in my ViewController, or just using the data from that class in my button method. I would be content using either method as long as it works haha.

As far as implementing the button method inside of my ViewController, I haven't even gotten close to getting that to work (I don't think) so I don't have much code to post for that. Here is the rest of it though:

@interface BasicComboGenViewController : UIViewController <UIActionSheetDelegate>{

UITextField *editAddCombo;
}
@property (nonatomic, retain)IBOutlet UITableView *myTableView;


@interface BeginningButton: UITableViewCell{
UIButton *editButton;

}

-(IBAction)editButton:(id)sender;
@end


Obviously there is more code than that, but I think this is all you were asking for, if there is more then please let me know

Edit: forgot the cell initiation

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
BasicComboGenAppDelegate *mainDelegate = (BasicComboGenAppDelegate *)[[UIApplication sharedApplication] delegate];


static NSString *CellIdentifier = @"BasicComboGen";

//CustomCell *
BeginningButton *cell = [myTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle]loadNibNamed:@"BeginningCell" owner:self options:nil];

for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[BeginningButton class]]) {
cell = (BeginningButton *)currentObject;
break;
}
}
}

// Set up the cell...
NSString *cellValue = [[mainDelegate.comboArray objectAtIndex:indexPath.row] savedCombo];
//[cell.textLabel setText:cellValue];
cell.test.text = cellValue;

return cell;
}


The cell works fine, and when I save necessary data, a new cell is added appropriately. The only problem I have is with accessing the button inside of the cell

dejo
Feb 10, 2012, 03:40 PM
So, is it BeginningButton's editButton: method that you are trying to call from within your tableViewController? If so, whereabouts do you want to call it? Will you have a reference to the desired instance of the BeginningButton class at that point?

P.S. You might want to consider renaming your editButton: method. It could easily be confused with your editButton ivar.

Abrexas
Feb 10, 2012, 03:58 PM
So, is it BeginningButton's editButton: method that you are trying to call from within your tableViewController? If so, whereabouts do you want to call it? Will you have a reference to the desired instance of the BeginningButton class at that point?

P.S. You might want to consider renaming your editButton: method. It could easily be confused with your editButton ivar.

TBH I don't know why I put the ivar there haha.

Yes I am trying to call the editButton: method inside of ViewController. I would like to call it anywhere that works really haha.

How this is supposed to work is: Each cell contains a string and a button. There is an empty TextField above all the cells. When I click the button pin one of the cells (editButton:) I need the string that is in that cell to be copied to the TextFeild (editAdddCombo)
For now, all I need to know is how to connect that button to the TextField and I can do the rest on my own.
There are more variable that are included in my plan, but if I can figure it out for one of them then I can use that technique for all the others.

dejo
Feb 10, 2012, 05:11 PM
How this is supposed to work is: Each cell contains a string and a button. There is an empty TextField above all the cells. When I click the button pin one of the cells (editButton:) I need the string that is in that cell to be copied to the TextFeild (editAdddCombo)

Hmm, this is a different problem than I was originally envisioning. You might wanna take a peek at this blog post (Getting Answers (http://www.mikeash.com/getting_answers.html)) so we all spend less time getting to the root of the problem.

So, I think I would tackle this issue by making your tableViewController a delegate for your button action. Since it has access to the strings and the textField, it's better equipped to copy the text into the field. The trick is having the delegate method know which row from the table the edit action came from. I would probably set the tag for each button to indicate which row it's for and then pass that along to the delegate.

Abrexas
Feb 11, 2012, 05:58 PM
Hrmm... well if this is going to be even tougher than I imagined, then maybe I have a new question lol.

If so then please watch my updated video about my app, that way my question will make more sense haha.

http://www.youtube.com/watch?v=WwmCd9aKw-4

Okay so as you can see (if you watched), my app creates these strings and adds them to an array. The custom cells are then filled with the strings in that array.
All I am really looking to do at this point is to make it easy for people to delete from their list as needed. I THINK I could figure out how to use the custom cell's button to just delete the element that that cell contains. But do you think that would be the met user friendly idea?

This time I'm not asking for code (unless someone knows how to solve the original problem)
I am just curious as to what might be the most efficient way to make this... notepad-esque feature look good.

phantax
Feb 11, 2012, 06:12 PM
I took a look at your video. Unless I am missing something obvious I think your question pertains to the view that is blue.

Is the ViewController for this view also the delegate and datasource for the TableView?

Isn't that ViewController also controlling the UITextField that you wish to use?

Can't you just set the text in the UITextField from didSelectRowAtIndexPath via an IBOutlet on the UITextField?

Abrexas
Feb 11, 2012, 06:28 PM
I took a look at your video. Unless I am missing something obvious I think your question pertains to the view that is blue.

Is the ViewController for this view also the delegate and datasource for the TableView?

Isn't that ViewController also controlling the UITextField that you wish to use?

Yes the blue view is the one I am working with. The whole thing is made in a .xib that is connected to ViewController. Except the custom cell is made in a .xib that is connected to my second class.
And yes, the ViewController is controlling the TextField, but the button I am trying to use is in my TableViewCell


Can't you just set the text in the UITextField from didSelectRowAtIndexPath via an IBOutlet on the UITextField?

I'm not sure what you mean here. I dunno why, but I can't picture what you are saying in my head haha

Abrexas
Feb 11, 2012, 07:22 PM
Okay so I have learned something.

From within my CustomCell's button method, I tried calling a method from my ViewController. The method I called was

-(IBAction)deleteSavedData{
BasicComboGenAppDelegate *mainDelegate = (BasicComboGenAppDelegate *)[[UIApplication sharedApplication] delegate];

if([mainDelegate.comboArray count] == 0)
NSLog(@"The file is empty");
else {
[mainDelegate.comboArray removeObjectAtIndex:0];
NSLog(@"Deleting object at index 0");
[myTableView reloadData];
}
}


This actually worked! It successfully deleted the ver first element of the array, but it didn't update the view. (which should have been done by [myTableView reloadData])
So I guess that this means that inside of my CustomCell class I can manipulate the delegate class, but I can't do so with the ViewContoller?
This makes sense as to why all my other attempts have been failures, but it doesn't help me 100%
I am not completely familiar with delegates and all that.

Hopefully this makes more sense to one of you haha. I will be satisfied if all I can do is use the cell's button to delete a cell (and refresh the page)

Abrexas
Feb 11, 2012, 09:22 PM
So, I think I would tackle this issue by making your tableViewController a delegate for your button action. Since it has access to the strings and the textField, it's better equipped to copy the text into the field.

This makes a lot more sense to me now. I have looked up a lot on it, and have tried to implement it, but I keep getting it wrong. I tried

BasicComboGenViewController *object=(BasicComboGenViewController *)[[UIApplication sharedApplication] delegate];

[object editTextField].text = @"test";


But I got error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BasicComboGenAppDelegate editAddCombo]: unrecognized selector sent to instance 0x6a51000'


Pretty sure I did it wrong haha

dejo
Feb 11, 2012, 11:23 PM
I believe you have the application delegate confused with setting a class as a delegate, normally done using a protocol.

Abrexas
Feb 12, 2012, 01:51 PM
using a protocol.

The section in my book talking about protocols only mentions for making new methods. I need to access a previously made method. As I said before, I have been able to use the CustomCells button to delete from an array saved in my BasicComboGenAppDelegate. An explanation that I found online was saying that The reason the view will not refresh, or why I can't get anything to show up in the TextField is because my
BasicComboGenViewController *object =[[BasicComboGenViewController alloc]init];

Is being declared, but isn't actually pointing to the ViewController class. Which I guess explains why when I use my button to run a method that deletes from the array and then refreshes the table, only the delete works and the refresh is skipped.

So how I see it, I need to get better with this whole delegation thing. I've tried reading the book, but it doesn't quite make sense to me. I will keep checking online though. But if you think of something else then please let me know.

Thanks for all the feedback!
- Steven French

dejo
Feb 13, 2012, 10:17 AM
Hmm, further pondering...

Perhaps, you can just take advantage of the target-action pattern (https://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/AppDesignBasics/AppDesignBasics.html#//apple_ref/doc/uid/TP40007072-CH2-SW2). In this case, your target would not be the UITableViewCell subclass but rather the UITableViewController.

Abrexas
Feb 19, 2012, 05:26 PM
thank you for all the help. But unfortunately I have given up on this for now. I have completed what I need to do, but in a much less user friends way, and I will probably come back to it some time later.

For now I will just write it off as impossible =P

- Steven French