iOS Delegation

nashyo

macrumors 6502
Original poster
Oct 1, 2010
299
0
Bristol
After selecting a row in my table view, the user is presented with a question.

When the user answers that question correctly, by selecting a round rect button that is hidden behind a label containing the answer text, the user is segued (modal) into the feedback view controller. A round rect button dismiss's the view.

table view controller (questions) -> view controller (question) - >view controller (answer feedback) <-dismiss back to question view controller.

On the view controller (question), I want the answer to mark as correct. In addition, I want the table view controller to present a check mark, declaring that question as complete.

What do I need to study next in order to achieve this? I realise that I will need to know about NSUserData to store the users answer if they were to quit the app half way through the quiz.

Am I right in saying that I will need to learn about delegation, to feedback the correct answer to the controllers?

Please help
Thanks
Rob
 

larswik

macrumors 68000
Sep 8, 2006
1,552
11
I am also learning so take my advice with a grain of salt. If you are asking about delegates I assume that you have never worked with a UITableView. You need to work with delegates in order to make TableViews work.

I would read up on TableView Doc's and learn to work with them before you jump into a bigger project.

Start small.
 

nashyo

macrumors 6502
Original poster
Oct 1, 2010
299
0
Bristol
My table view works?

I have set up the data source and the table view, at runtime, shows my content. When I select my content the table view segues on, just fine.
I haven't overridden the delegate method below, at all.

I'm coding in Xcode 4.2.

Code:
Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
When would i want to call this table view delegate method?
 

KnightWRX

macrumors Pentium
Jan 28, 2009
15,046
4
Quebec, Canada

nashyo

macrumors 6502
Original poster
Oct 1, 2010
299
0
Bristol
Are you sure?

I don't understand how a protocol can help me in this way. I've just studied it for two hours and this is what I understand.

A protocol details required or optional method(s) must be called in any class that declares itself as a delegate of said protocol. This provides a form of consistency and documentation during app development, mainly for bug finding.

A view will delegate a task to a controller, which will act out that task, usually calling on the model to do so. The end result of that task returns to the SAME view.

I need the table view to re-draw with a checkmark for any given row containing the question that was answered correctly.
 

naphatkrit

macrumors member
Jul 18, 2011
38
0
I'm new to programming too, but I have done a checklist app. Keep in mind that i used interface builder and do not know how storyboard works. What I did was in the nsmutablearray that my table is reading the data from. Each entry of the array is a namutabledictionary with two keys, name and completed. Under completed, I use the [NSNumber numberWithBOOL:] to indicate whether the entry has been completed. Now in the table view data source, under cellForRowAtIndexPath, I have the view controller check for the number under the key completed. If it's 1 (BOOL value Yes], write a code to add checkmark to the row. Now, all you have to do is pass along the dictionary of the question to your modal view in a custom init method. If the user answers the question correctly, change the value under the key completed to [NSNumber numberWithBOOL: YES], then when the modal view is dismissed, put [tableView reloadData] under viewWillAppear for the table view controller. I hope that helps.
 

nashyo

macrumors 6502
Original poster
Oct 1, 2010
299
0
Bristol
Confused

I get this
I'm new to programming too, but I have done a checklist app. Keep in mind that i used interface builder and do not know how storyboard works.

What I did was in the nsmutablearray that my table is reading the data from. Each entry of the array is a namutabledictionary with two keys, name and completed. Under completed, I use the [NSNumber numberWithBOOL:] to indicate whether the entry has been completed.

Now in the table view data source, under cellForRowAtIndexPath, I have the view controller check for the number under the key completed. If it's 1 (BOOL value Yes], write a code to add checkmark to the row.
I don't get this
Now, all you have to do is pass along the dictionary of the question to your modal view in a custom init method. If the user answers the question correctly, change the value under the key completed to [NSNumber numberWithBOOL: YES], then when the modal view is dismissed, put [tableView reloadData] under viewWillAppear for the table view controller. I hope that helps.
A custom init method initialising what?
Passing the object from where?
How does the user input a correct answer in your checklist?

Thanks
Rob
 

naphatkrit

macrumors member
Jul 18, 2011
38
0
First of all, how do you pass along the question from your tableview to your modal view? what I did with my checklist app was this. By default, a view controller has the method:
Code:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    }
    return self;
}
If you view controller doesn't have it, you can just copy and pate that code. Now, I simply modify the code to look like this:
Code:
- (id)initWithNibName:(NSString *)nibNameOrNil forQuestion:(NSMutableDictionary *)question bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.selectedQuestion = question;
    }
    return self;
}
and add - (id)initWithNibName:(NSString *)nibNameOrNil forQuestion:(NSMutableDictionary *)question bundle:(NSBundle *)nibBundleOrNil; to my .h file. Now, in the table's view controller, under didSelectRowAtIndexPath, use the indexPath to find the appropriate question (which is an NSMutableDictionary), and use the method I just made to initialize the modal view controller.

When the user answers the question correctly, simply use this line of code:
Code:
[self.selectedQuestion setValue:[NSNumber numberWithBool:YES] forKey:@"completed"];
[self dismissModalViewControllerAnimated:YES];
Add [tableView reloadData] to your viewWillAppear of the table's View Controller, and you should be good to go.
 
Last edited:

KnightWRX

macrumors Pentium
Jan 28, 2009
15,046
4
Quebec, Canada
I don't understand how a protocol can help me in this way. I've just studied it for two hours and this is what I understand.

A protocol details required or optional method(s) must be called in any class that declares itself as a delegate of said protocol. This provides a form of consistency and documentation during app development, mainly for bug finding.

A view will delegate a task to a controller, which will act out that task, usually calling on the model to do so. The end result of that task returns to the SAME view.

I need the table view to re-draw with a checkmark for any given row containing the question that was answered correctly.
Your Question controller signals the tableview controller with a BOOL value for the question answered.

Protocols permit calling implemented methods in the delegate. Set your tableview controller as a delegate of the Question view controller. Create a protocol in the Question view controller that the tableview controller implements.

Then it's a simple matter of calling it from the question view controller :

Code:
[[self delegate] answerWasRight: YES];
This is exactly what Protocols are for.

You can then implement answerWasRight: (BOOL) rightorwrong as you see fit (it can update the table view with a red X or green Check depending on the BOOL value if that is what you want).

Read the 2nd link in my first post. It's a downright simple tutorial on how to implement exactly this functionality.