cs193p – Assignment #1 Extra Task

Please note, this blog entry is from a previous course. You might want to check out the current one.

Add a UISlider to your UI which travels through the history of the currently-being- played game’s flips and display it to the user (moving the slider will modify the contents of the text label you created for Required Task #3 to show its state over the course of the game). When you are displaying past flips, you probably want the text label to be grayed out (with alpha) or something so it’s clear that it’s “the past.” Also, you probably don’t want that text label from Required Task #3 to ever be blank (except at the very start of the game, of course). And every time a new flip happens, you probably want to “jump to the present” in the slider. Implementing this extra credit item will require you to familiarize yourself with UISlider’s API and to add a data structure to your Controller to keep track of the history. It can be implemented in fewer than a dozen lines of code.

Add a new property to hold the history information and initialize it using its getter:

@property (strong, nonatomic) NSMutableArray *history;
...
- (NSMutableArray *)history {
    if (!_history) {
        _history = [[NSMutableArray alloc] init];
    }
    return _history;
}

When flipping a card add the resulting message to the history if it has changed:

- (IBAction)flipCard:(UIButton *)sender
{
    ...
    if (![[self.history lastObject] 
      isEqualToString:self.game.descriptionOfLastFlip])
        [self.history addObject:self.game.descriptionOfLastFlip];
    [self updateUI];
}

Reset the history when a new deck is dealt:

- (IBAction)dealButtonPressed:(UIButton *)sender {
    ...
    self.history = nil;
    [self updateUI];
}

Add a slider in storyboard:

cs193p – Assignment #1 Extra Task
cs193p – Assignment #1 Extra Task

Create an outlet to access the slider element from the view controller:

@property (weak, nonatomic) IBOutlet UISlider *historySlider;

Create a helper method to set the range of the slider according to the available history:

- (void)updateSliderRange
{
    int maxValue = [self.history count] - 1;
    if (maxValue < 0) maxValue = 0;
    self.historySlider.maximumValue = maxValue;
    [self.historySlider setValue:maxValue animated:YES];
}

Which is called when the user interfaces updates, at the same time make sure the text label is not grayed out:

- (void)updateUI
{
    ...
    self.resultOfLastFlipLabel.alpha = 1;
    self.resultOfLastFlipLabel.text = self.game.descriptionOfLastFlip;
    [self updateSliderRange];
}

Finally create an action method for when the slider is moved. It ensures to use only discrete values, and changes the text label when necessary (together with its grayness):

- (IBAction)historySliderChanged:(UISlider *)sender {
    int sliderValue;
    sliderValue = lroundf(self.historySlider.value);
    [self.historySlider setValue:sliderValue animated:NO];

    if ([self.history count]) {
        self.resultOfLastFlipLabel.alpha = 
          (sliderValue + 1 < [self.history count]) ? 0.6 : 1.0;
        self.resultOfLastFlipLabel.text = 
          [self.history objectAtIndex:sliderValue];        
    }
}

The complete code is available on github.

FacebooktwitterredditpinterestlinkedintumblrmailFacebooktwitterredditpinterestlinkedintumblrmail

Leave a Reply

Your email address will not be published.