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.
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