Skip navigation

Counter across 3 View Controllers?

1557 Views 34 Replies Latest reply: Oct 7, 2013 1:40 AM by JDL55 RSS
1 2 3 Previous Next
JDL55 Calculating status...
Currently Being Moderated
Feb 2, 2013 9:11 PM

Need a way to make a counter work across at least 3 View Controllers.

One view controller has an -(IBAction)plus1 button and an -(IBAction)plus 0 button.

 

Those buttons segue to the next view controller, that has an -(IBAction)plus2 button and an -(IBAction)plus 0 button.... etc.

 

Each segues and adds all button clicks through to the last view controller with an IBOutlet UILabel *count text label.

 

I got this to work on one view controller. Can't figure out how to make it work across 3VCs. Someone suggested Singleton?

Thanks for any thoughts.

 

Thanks JDL55

  • Frank Caggiano Level 7 Level 7 (22,830 points)
    Currently Being Moderated
    Feb 3, 2013 6:59 AM (in response to JDL55)

    So the display is in one view and the buttons are in multiple different views?

  • Llessur999 Level 4 Level 4 (1,155 points)
    Currently Being Moderated
    Feb 3, 2013 9:53 AM (in response to Frank Caggiano)

    Singleton sounds like over-complication. You need to decide where the model should be, and reference it from each view controller. In your case, the model is just a single integer value, so very simple. The easiest approach is just to add a property to the application delegate (AppDelegate.h).

     

    @property (nonatomic) int currentValue;


    Adjust the value during segues (FirstViewController.m, SecondViewController.m, etc.). This assumes each segue has been assigned an identifier in the storyboard.

     

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

    {

        AppDelegate *appDelegate = UIApplication.sharedApplication.delegate;

        if ([segue.identifier isEqualToString:@"plus1"]) {

            appDelegate.currentValue += 1;

        }

        else if ([segue.identifier isEqualToString:@"plus0"]) {

            // no action

        }

    }

     

    In the final view, set the label text (LastViewController.m).

     

    - (void)viewDidLoad

    {

        [super viewDidLoad];

        AppDelegate *appDelegate = UIApplication.sharedApplication.delegate;

        self.currentValueLabel.text = [[NSNumber numberWithInt:appDelegate.currentValue] stringValue];

    }

     

    You should immediately see there is lots of room for improvement if this is a real app, but do the simple case first to make sure you get the concept. Potential areas for improvement after that:

    1. Encode the math operation increment in the identifier so instead of if/else in prepareForSegue, you can just parse the identifier and perform the math operation. Then you could add buttons/segues without changing any code.
    2. Allow an initial value to be set, then continue to perform math operations on the current value as the user goes up/down the view controller stack. Show the current value on each view.
    3. Use a single UIViewController class for all of the storyboard views with math operation buttons.
    4. Instead of attaching the model to the application delegate, which is not very flexible, pass the model into a property of each view controller during prepareForSegue.
  • Llessur999 Level 4 Level 4 (1,155 points)
    Currently Being Moderated
    Feb 3, 2013 12:00 PM (in response to JDL55)

    The concept I described will work fine for that. On each storyboard view, set the segue identifier for either the yes or no button to some standard text like correctAnswer. Then do this in prepareForSegue.

     

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

    {

        AppDelegate *appDelegate = UIApplication.sharedApplication.delegate;

        if ([segue.identifier isEqualToString:@"correctAnswer"]) {

            appDelegate.currentValue += 1;

        }

    }

     

    I notice your storyboard only has a single segue from one scene to the next. To use the concept I described, you need two segues: one for each button. The source for each segue should be the button itself, not the view controller. Otherwise you will need to add button action handlers and programmatically invoke the segue. That is more complicated and not necessary.

     

    Since these are modal segues, you need some way for the user to dismiss the stack of modal views. For example, a button on the final view.

     

    Your storyboard looks like it has a navigation controller off the screenshot to the left. So you could be using push segues rather than modal segues if you want the user to be able to backtrack to a prior question using the navigation bar.

     

    Using a separate view for each question is fine if this is just an exercise or the question count is very small. But if this is a real questionairre app, stacking up modal views like that is not optimal. The question text and correct answer for all questions should be part of your model. A single question view would show the question text for the current question.

  • Llessur999 Level 4 Level 4 (1,155 points)
    Currently Being Moderated
    Feb 4, 2013 10:31 AM (in response to JDL55)

    These are basic compile errors.

     

    Use of undeclared identifier "appDelegate".

    The type AppDelegate is not understood. You need to add #import "AppDelegate.h"to reference AppDelegate in a module.

     

    Use of undeclared identifier "initWithNIbName".

    Function prepareForSegue is missing a closing brace, so the compiler is attempting to resolve initWithNibName within the scope of prepareForSegue.

     

    Since I use segues, I don't think I need to use the IBActons correct

    For this particular scenario you can use only segues.

     

    Do I need to tell the AppDelegate where to display the data?

    AppDelegate does not display the data, just store it.

     

    The label on the destination view controller was called 

    IBOutlet UILabel *count;

    it is not connected to anything right now just idle.

    This IBOutlet is equivalent to currentValueLabel in my first post. Per the example I provided, you should set the label text in the viewDidLoad of the view controller containing this label.

     

    An approach that might make learning this easier for you: Build this up from scratch, one step at a time, testing in the simulator as you add each bit of functionality. Then you know exactly what causes something to go wrong.

  • Llessur999 Level 4 Level 4 (1,155 points)
    Currently Being Moderated
    Feb 8, 2013 12:47 PM (in response to JDL55)
    Line 22 (Use of undeclared identifier 'initWithNitName') Not sure where you wanted to place the bracket.

    Match up every brace. In the screenshot a few posts up, prepareForSeque does not have a closing brace. I am on a PC right now but like other IDE's, Xcode probably shows the brace range for the current insertion point in the gutter at the left side of the editor.

     

    Line 58 (Property 'currentValueLabel' not found on object of type 'EndViewController*')

    As I mentioned, currentValueLabel is the name of the IBOutlet for the UILabel on the last view controller.  Change this to whatever your outlet is named.

  • Llessur999 Level 4 Level 4 (1,155 points)
    Currently Being Moderated
    Feb 10, 2013 11:38 AM (in response to JDL55)

    I suspect one of two problems.

     

    1. An error in prepareForSegue. Put a breakpoint on prepareForSegue and step through each line to make sure it works. If it doesn't even get to the breakpoint, it is probably #2.

     

    2. You formerly had IBActions for the buttons. If you just deleted the functions (the code) but did not update the storyboard by disconnecting the event, pressing the button will fault because it tries to execute the function, which does not exist. Select the button and view the connections in the Connections Inspector. If you see any connected event such as the Touch Up Inside in the picture below, if the target no longer exists, disconnect the event by pressing the small X.  Note: This is a common problem in many IDEs that have designers. If this is what caused the SIGABRT, in the debug output you will see something like this that tells you the reason: "'NSInvalidArgumentException', reason: '-[MiddleViewController yesButtonClick:]: unrecognized selector sent to instance."

    temp1.png

     

    This is a good reason for my advice to build the app from scratch, add one piece of functionality at a time, test each addition. Then when a fault occurs, you know it was caused by the last incremental change.

  • dineshmsc2 Calculating status...
    Currently Being Moderated
    Sep 21, 2013 9:02 AM (in response to JDL55)

    hello sir are you a developer if you then please told me please please i am in problem with my iphone 4  

     

    <Email Edited By Host>

1 2 3 Previous Next

Actions

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • This solved my question - 10 points
  • This helped me - 5 points
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Support Communities Terms of Use.