iosiphonecocoa-touchuiimagewalkthrough

Play iOS In-App Tutorial Again From In-App Settings When the User Selects "Play Tutorial Again"


I have created a simple iPhone application that has a tutorial (a series of 5 images) when the user downloads the app for the very first time where they can click Next and cycle through the images. Currently there's no way to play the tutorial again but in my update, I'd like to introduce this feature, some like apps have within their settings of the app itself.

I have a Tab Bar with three table view controllers Timeline, Event and Settings. When the user goes to the Settings tab and selects the "Play Tutorial Again" Table View Cell, I want that to start the tutorial again.

In my Timeline View (the root view), I have the following code:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];        
    if ([TutorialViewController hasSeenTutorial] == NO) {
    NSArray *tutorialImages = @[[UIImage imageNamed:@"Tutorial 1.png"],
                                        [UIImage imageNamed:@"Tutorial 2.png"],
                                        [UIImage imageNamed:@"Tutorial 3.png"],
                                        [UIImage imageNamed:@"Tutorial 4.png"],
                                        [UIImage imageNamed:@"Tutorial 5.png"]];
    TutorialViewController *tutorial = [[TutorialViewController alloc] initWithImages:tutorialImages];
    [self presentViewController:tutorial animated:YES completion:nil];
    [TutorialViewController setHasSeenTutorial:YES];
        }
}

- (void)displayTutorial
{

    NSArray *tutorialImages = @[[UIImage imageNamed:@"Tutorial 1.png"],
                                [UIImage imageNamed:@"Tutorial 2.png"],
                                [UIImage imageNamed:@"Tutorial 3.png"],
                                [UIImage imageNamed:@"Tutorial 4.png"],
                                [UIImage imageNamed:@"Tutorial 5.png"]];

    TutorialViewController *tutorial = [[TutorialViewController alloc] initWithImages:tutorialImages];
    [self presentViewController:tutorial animated:YES completion:nil];
}

The TutorialViewController's code is:

static NSString * const kHasSeenTutorial = @"hasSeenTutorial";

+ (BOOL)hasSeenTutorial
{
    return [[NSUserDefaults standardUserDefaults] boolForKey:kHasSeenTutorial];
}

+ (void)setHasSeenTutorial:(BOOL)hasSeenTutorial
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setBool:hasSeenTutorial forKey:kHasSeenTutorial];
    [defaults synchronize];
}

- (id)initWithImages:(NSArray *)imageArray
{
    self = [super init];
    if (self) {
        if (imageArray == nil) {
            [[NSException exceptionWithName:NSInvalidArgumentException reason:@"imageArray cannot be nil." userInfo:nil] raise];
        }
        self.images = imageArray;
    }
    return self;
}

- (void)loadView
{
    [super loadView];
}

- (void)viewDidLoad
{

    [super viewDidLoad];

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [self.view addSubview:imageView];
    self.imageView = imageView;

    CGRect buttonFrame = [[UIScreen mainScreen] bounds];

        buttonFrame.origin.y = 519.0;
        buttonFrame.origin.x = 250.0;
        buttonFrame.size.height = 51.0;
        buttonFrame.size.width = 70.0;

        UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

        [nextButton setTitle:@"Next" forState:UIControlStateNormal];
        [nextButton addTarget:self action:@selector(nextButtonWasTapped:) forControlEvents:UIControlEventTouchUpInside];

        nextButton.frame = buttonFrame;
        nextButton.backgroundColor = [UIColor whiteColor];

        nextButton.showsTouchWhenHighlighted = YES;
        nextButton.adjustsImageWhenHighlighted = NO;
        nextButton.tintColor = [UIColor purpleColor];
        nextButton.titleLabel.font = [UIFont systemFontOfSize:18.0];
        nextButton.opaque = NO;

        [self.view addSubview:nextButton];
        self.nextButton = nextButton;

        // ----------------------------------------------------------------------

        currentIndex = 0;

        if (self.images == nil) {
            self.images = @[];
        }


}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self resetToStart];
}

- (void)setImages:(NSArray *)images
{
    _images = images;
    [self resetToStart];
}

- (void)resetToStart
{
    [self.nextButton setTitle:@"Next" forState:UIControlStateNormal];
    currentIndex = 0;
    if (currentIndex < self.images.count) {
        self.imageView.image = self.images[currentIndex];
    }

    [self.view bringSubviewToFront:self.nextButton];
}

- (void)nextButtonWasTapped:(id)sender
{
    currentIndex++;
    if (currentIndex < self.images.count) {
        self.imageView.image = self.images[currentIndex];

        if (currentIndex == self.images.count - 1) {
            [self.nextButton setTitle:@"Start" forState:UIControlStateNormal];
        }
    }

    if (currentIndex == self.images.count) {
        [self dismissViewControllerAnimated:YES completion:nil];
        [EnvylopeTutorialViewController setHasSeenTutorial:YES];
    }
}

From the looks of it, I'm guessing I would just do something like call ResetToStart, or something similar, but I'm really not sure how I would do this. The Images are communicated in the Timeline but I'm playing the tutorial from the Settings, so I'm guessing I would have to set up some similar methods in the Settings Table View, etc. I'm really lost on this one

So from the Settings Tab, I'd like to be able to play the tutorial all over again with the same images, buttons, etc by clicking on the "Play Tutorial" Table View Cell.

In the App Settings View Controller, I have:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if ([cell.textLabel.text isEqualToString:@"Play Tutorial Again"])
    {
        NSLog(@"The Tutorial is going to play"); 
        [self displayTutorial]; 
    }


}

But the displayTutorial method isn't being called.

Any guidance on this would be really appreciated.


Solution

  • Just invoke your Tutorial code with didSelectRow in your settings view, omitting the hasSeenTutorial code

    Place TutorialViewController *tutorial = [[TutorialViewController alloc] initWithImages:tutorialImages]; in your didSelectRow method in your settingsViewController to present the tutorial at any time