1 2 3 Previous Next 34 Replies Latest reply: Oct 7, 2013 1:40 AM by JDL55
JDL55 Level 1 Level 1 (0 points)

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

  • 1. Re: Counter across 3 View Controllers?
    Frank Caggiano Level 7 Level 7 (23,840 points)

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

  • 2. Re: Counter across 3 View Controllers?
    Llessur999 Level 4 Level 4 (1,170 points)

    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.
  • 3. Re: Counter across 3 View Controllers?
    JDL55 Level 1 Level 1 (0 points)

    HI, thanks for responding. I will try your idea. You're right it seems simple to me but just starting to learn so

  • 4. Re: Counter across 3 View Controllers?
    JDL55 Level 1 Level 1 (0 points)

    ...so thanks for taking the time. Below is what I'm visually trying to accomplish.

    It's not an incrementCounter. Each button passes a certain value to the label.

    COUNTER.jpg

    This is what it looks like now on a single view controller and it works great:

    I'll start working on prepare for Seque: Got my fingers crossed... Ha.

    If you see something else just let me know. Thanks Llessur999and Frank!

    I'll report back.

    COUNTER1 scene.jpg

  • 5. Re: Counter across 3 View Controllers?
    Llessur999 Level 4 Level 4 (1,170 points)

    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.

  • 6. Re: Counter across 3 View Controllers?
    JDL55 Level 1 Level 1 (0 points)

    Hello, I'm progressing really well but reached a stumbling block. I'm getting red circle errors...

    Use of undeclared identifier "appDelegate". Use of undeclared identifier "initWithNIbName".

    Since I use segues, I don't think I need to use the IBActons correct? I used your first idea, plus1 for the Yes segue and plus0 for the No segue since they need different values.

    I know we're close, do you see anything I need to do? See screen shots below.

    Screen Shot1.png

    Screen Shot2.png

  • 7. Re: Counter across 3 View Controllers?
    JDL55 Level 1 Level 1 (0 points)

    Do I need to tell the AppDelegate where to display the data? The label on the destination view controller was called

        IBOutlet UILabel *count;

    it is not connected to anything right now just idle.

     

    Or does the destination view controller need to declare a public property?

    Thanks

  • 8. Re: Counter across 3 View Controllers?
    Llessur999 Level 4 Level 4 (1,170 points)

    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.

  • 9. Re: Counter across 3 View Controllers?
    JDL55 Level 1 Level 1 (0 points)

    Hi, I'm so close. Just a couple errors to correct and I can run it.

    Made numbers next to lines just to identify, they are not in the code.

    Line 22 (Use of undeclared identifier 'initWithNitName') Not sure where you wanted to place the bracket.

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

    Thoughts?

     

    FirstViewController.m

    15     MrWizoAppDelegate *appDelegate = UIApplication.sharedApplication.delegate;

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

    17         appDelegate.currentValue += 1;

    18    }

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

    20         appDelegate.currentValue += 0;

    21    }

       

    22 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    23 {

    24    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    25    if (self) {

    26        // Custom initialization

    27    }

    28    return self;

    =========================

     

    EndViewController.m

    56    [super viewDidLoad];

    57    MrWizoAppDelegate *appDelegate = UIApplication.sharedApplication.delegate;

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

    59 }

     

    60 - (void)didReceiveMemoryWarning

    61 {

    62    [super didReceiveMemoryWarning];

        // Dispose of any resources that can be recreated.

    63 }

     

    64 @end

     



  • 10. Re: Counter across 3 View Controllers?
    Llessur999 Level 4 Level 4 (1,170 points)
    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.

  • 11. Re: Counter across 3 View Controllers?
    JDL55 Level 1 Level 1 (0 points)

    Alright! Build Successful.... thank you very much! Uh oh..

    Screen Shot 2013-02-09 at 2.14.30 AM.png

    No action on the Yes or No button.  And a green signal appears in AppDelegate when I push

    those buttons. Googled but no solid fixes. Any thoughts here?

    Hey do you hire out for fixing xcode projects?

    JDL55

  • 12. Re: Counter across 3 View Controllers?
    Llessur999 Level 4 Level 4 (1,170 points)

    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.

  • 13. Re: Counter across 3 View Controllers?
    JDL55 Level 1 Level 1 (0 points)

    Hello,

    Thanks so much. It is working great.

    I have only one minor fix and that is how to clear the UILabel back to zero.

    I thought maybe on last VC.....

    .h file:

    @property (retain, nonatomic) IBOutlet UILabel *currentValueLabel;

     

    -(IBAction)zero;

     

    .m file:

    -(IBAction)zero {

        _currentValueLabel=0;

        _currentValueLabel.text = [NSString

                      stringWithFormat:@"%@", _currentValueLabel];

     

     

    It builds and runs but when I click on this new reset button nothing happens.

    Any thoughts?

    Thanks

  • 14. Re: Counter across 3 View Controllers?
    dineshmsc2 Level 1 Level 1 (0 points)

    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